*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
import android.graphics.*;
import android.graphics.drawable.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_12.*;
+
+class SavedState {
+ long received_time;
+ int state;
+ boolean locked;
+ String callsign;
+ int serial;
+ int flight;
+ int rssi;
+
+ SavedState(AltosState state) {
+ received_time = state.received_time;
+ this.state = state.state();
+ if (state.gps != null)
+ locked = state.gps.locked;
+ else
+ locked = false;
+ callsign = state.cal_data().callsign;
+ serial = state.cal_data().serial;
+ flight = state.cal_data().flight;
+ rssi = state.rssi;
+ }
+}
+
+class Tracker implements CharSequence, Comparable {
+ int serial;
+ String call;
+ double frequency;
+
+ String display;
+
+ public Tracker(int serial, String call, double frequency) {
+ if (call == null)
+ call = "none";
+
+ this.serial = serial;
+ this.call = call;
+ this.frequency = frequency;
+ if (frequency == 0.0)
+ display = "Auto";
+ else if (frequency == AltosLib.MISSING) {
+ display = String.format("%-8.8s %6d", call, serial);
+ } else {
+ display = String.format("%-8.8s %7.3f %6d", call, frequency, serial);
+ }
+ }
+
+ public Tracker(AltosState s) {
+ this(s == null ? 0 : s.cal_data().serial,
+ s == null ? null : s.cal_data().callsign,
+ s == null ? 0.0 : s.frequency);
+ }
+
+ /* CharSequence */
+ public char charAt(int index) {
+ return display.charAt(index);
+ }
+
+ public int length() {
+ return display.length();
+ }
+
+ public CharSequence subSequence(int start, int end) throws IndexOutOfBoundsException {
+ return display.subSequence(start, end);
+ }
+
+ public String toString() {
+ return display.toString();
+ }
+
+ /* Comparable */
+ public int compareTo (Object other) {
+ Tracker o = (Tracker) other;
+ if (frequency == 0.0) {
+ if (o.frequency == 0.0)
+ return 0;
+ return -1;
+ }
+ if (o.frequency == 0.0)
+ return 1;
+
+ int a = serial - o.serial;
+ int b = call.compareTo(o.call);
+ int c = (int) Math.signum(frequency - o.frequency);
+
+ if (b != 0)
+ return b;
+ if (c != 0)
+ return c;
+ return a;
+ }
+}
public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
// field to display the version at the bottom of the screen
private TextView mVersion;
- private double frequency;
- private int telemetry_rate;
-
private boolean idle_mode = false;
public Location location = null;
+ private AltosState state;
+ private SavedState saved_state;
+
// Tabs
TabHost mTabHost;
AltosViewPager mViewPager;
// Timer and Saved flight state for Age calculation
private Timer timer;
- AltosState saved_state;
+
TelemetryState telemetry_state;
- Integer[] serials;
+ Tracker[] trackers;
+
UsbDevice pending_usb_device;
boolean start_with_usb;
AltosPreferences.register_units_listener(this);
}
- serials = telemetry_state.states.keySet().toArray(new Integer[0]);
- Arrays.sort(serials);
+ int num_trackers = 0;
+ for (AltosState s : telemetry_state.states.values()) {
+ num_trackers++;
+ }
+
+ trackers = new Tracker[num_trackers + 1];
+
+ int n = 0;
+ trackers[n++] = new Tracker(0, "auto", 0.0);
+
+ for (AltosState s : telemetry_state.states.values())
+ trackers[n++] = new Tracker(s);
+
+ Arrays.sort(trackers);
update_title(telemetry_state);
if (telemetry_state.states.containsKey(current_serial)) {
state = telemetry_state.states.get(current_serial);
- int age = state_age(state);
+ int age = state_age(state.received_time);
if (age < 20)
aged = false;
if (current_serial == selected_serial)
for (int serial : telemetry_state.states.keySet()) {
AltosState existing = telemetry_state.states.get(serial);
- int existing_age = state_age(existing);
+ int existing_age = state_age(existing.received_time);
if (newest_state == null || existing_age < newest_age) {
newest_state = existing;
state = newest_state;
}
- update_ui(telemetry_state, state);
+ update_ui(telemetry_state, state, telemetry_state.quiet);
start_timer();
}
blend_component(a, b, r, 24, 0xff));
}
- int state_age(AltosState state) {
- return (int) ((System.currentTimeMillis() - state.received_time + 500) / 1000);
+ int state_age(long received_time) {
+ return (int) ((System.currentTimeMillis() - received_time + 500) / 1000);
}
void set_screen_on(int age) {
void update_age() {
if (saved_state != null) {
- int age = state_age(saved_state);
+ int age = state_age(saved_state.received_time);
double age_scale = age / 100.0;
}
}
- void update_ui(TelemetryState telem_state, AltosState state) {
+ void update_ui(TelemetryState telem_state, AltosState state, boolean quiet) {
+
+ this.state = state;
int prev_state = AltosLib.ao_flight_invalid;
AltosGreatCircle from_receiver = null;
if (saved_state != null)
- prev_state = saved_state.state();
+ prev_state = saved_state.state;
if (state != null) {
- set_screen_on(state_age(state));
+ set_screen_on(state_age(state.received_time));
if (state.state() == AltosLib.ao_flight_stateless) {
boolean prev_locked = false;
if(state.gps != null)
locked = state.gps.locked;
- if (saved_state != null && saved_state.gps != null)
- prev_locked = saved_state.gps.locked;
+ if (saved_state != null)
+ prev_locked = saved_state.locked;
if (prev_locked != locked) {
String currentTab = mTabHost.getCurrentTabTag();
if (locked) {
state.gps.alt);
}
- if (saved_state == null || !same_string(saved_state.callsign, state.callsign)) {
- mCallsignView.setText(state.callsign);
+ if (saved_state == null || !same_string(saved_state.callsign, state.cal_data().callsign)) {
+ mCallsignView.setText(state.cal_data().callsign);
}
- if (saved_state == null || state.serial != saved_state.serial) {
- if (state.serial == AltosLib.MISSING)
+ if (saved_state == null || state.cal_data().serial != saved_state.serial) {
+ if (state.cal_data().serial == AltosLib.MISSING)
mSerialView.setText("");
else
- mSerialView.setText(String.format("%d", state.serial));
+ mSerialView.setText(String.format("%d", state.cal_data().serial));
}
- if (saved_state == null || state.flight != saved_state.flight) {
- if (state.flight == AltosLib.MISSING)
+ if (saved_state == null || state.cal_data().flight != saved_state.flight) {
+ if (state.cal_data().flight == AltosLib.MISSING)
mFlightView.setText("");
else
- mFlightView.setText(String.format("%d", state.flight));
+ mFlightView.setText(String.format("%d", state.cal_data().flight));
}
- if (saved_state == null || state.state() != saved_state.state()) {
+ if (saved_state == null || state.state() != saved_state.state) {
if (state.state() == AltosLib.ao_flight_stateless) {
mStateLayout.setVisibility(View.GONE);
} else {
else
mRSSIView.setText(String.format("%d", state.rssi));
}
+ saved_state = new SavedState(state);
}
for (AltosDroidTab mTab : mTabs)
mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
+ AltosDebug.debug("quiet %b\n", quiet);
if (mAltosVoice != null)
- mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem());
+ mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet);
- saved_state = state;
}
private void onTimerTick() {
// Display the Version
mVersion = (TextView) findViewById(R.id.version);
mVersion.setText("Version: " + BuildInfo.version +
- " Built: " + BuildInfo.builddate + " " + BuildInfo.buildtime + " " + BuildInfo.buildtz +
- " (" + BuildInfo.branch + "-" + BuildInfo.commitnum + "-" + BuildInfo.commithash + ")");
+ (AltosVersion.has_google_maps_api_key() ? " maps" : "") +
+ " Built: " + BuildInfo.builddate + " " + BuildInfo.buildtime + " " + BuildInfo.buildtz +
+ " (" + BuildInfo.branch + "-" + BuildInfo.commitnum + "-" + BuildInfo.commithash + ")");
mCallsignView = (TextView) findViewById(R.id.callsign_value);
mRSSIView = (TextView) findViewById(R.id.rssi_value);
location.getLatitude(),
location.getLongitude());
- update_ui(telemetry_state, saved_state);
+ update_ui(telemetry_state, state, true);
}
@Override
}
}
- private void disconnectDevice() {
+ private void disconnectDevice(boolean remember) {
try {
- mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, null));
+ mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, (Boolean) remember));
} catch (RemoteException e) {
}
}
}
}
- void setFrequency(String freq) {
- try {
- setFrequency (AltosParse.parse_double_net(freq.substring(11, 17)));
- } catch (ParseException e) {
- }
+ void setFrequency(AltosFrequency frequency) {
+ setFrequency (frequency.frequency);
}
void setBaud(int baud) {
}
if (serial != 0) {
- for (i = 0; i < serials.length; i++)
- if (serials[i] == serial)
+ for (i = 0; i < trackers.length; i++)
+ if (trackers[i].serial == serial)
break;
- if (i == serials.length) {
+ if (i == trackers.length) {
AltosDebug.debug("attempt to select unknown tracker %d\n", serial);
return;
}
void touch_trackers(Integer[] serials) {
AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this);
builder_tracker.setTitle("Select Tracker");
- final String[] trackers = new String[serials.length + 1];
- trackers[0] = "Auto";
- for (int i = 0; i < serials.length; i++)
- trackers[i+1] = String.format("%d", serials[i]);
- builder_tracker.setItems(trackers,
+
+ final Tracker[] my_trackers = new Tracker[serials.length + 1];
+
+ my_trackers[0] = new Tracker(null);
+
+ for (int i = 0; i < serials.length; i++) {
+ AltosState s = telemetry_state.states.get(serials[i]);
+ my_trackers[i+1] = new Tracker(s);
+ }
+ builder_tracker.setItems(my_trackers,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0)
select_tracker(0);
else
- select_tracker(Integer.parseInt(trackers[item]));
+ select_tracker(my_trackers[item].serial);
}
});
AlertDialog alert_tracker = builder_tracker.create();
case R.id.disconnect:
/* Disconnect the device
*/
- disconnectDevice();
+ disconnectDevice(false);
return true;
case R.id.quit:
AltosDebug.debug("R.id.quit");
- disconnectDevice();
+ disconnectDevice(true);
finish();
return true;
case R.id.setup:
case R.id.select_freq:
// Set the TBT radio frequency
- final String[] frequencies = {
- "Channel 0 (434.550MHz)",
- "Channel 1 (434.650MHz)",
- "Channel 2 (434.750MHz)",
- "Channel 3 (434.850MHz)",
- "Channel 4 (434.950MHz)",
- "Channel 5 (435.050MHz)",
- "Channel 6 (435.150MHz)",
- "Channel 7 (435.250MHz)",
- "Channel 8 (435.350MHz)",
- "Channel 9 (435.450MHz)"
- };
+ final AltosFrequency[] frequencies = AltosPreferences.common_frequencies();
+ String[] frequency_strings = new String[frequencies.length];
+ for (int i = 0; i < frequencies.length; i++)
+ frequency_strings[i] = frequencies[i].toString();
AlertDialog.Builder builder_freq = new AlertDialog.Builder(this);
builder_freq.setTitle("Pick a frequency");
- builder_freq.setItems(frequencies,
+ builder_freq.setItems(frequency_strings,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
setFrequency(frequencies[item]);
alert_freq.show();
return true;
case R.id.select_tracker:
- if (serials != null) {
- String[] trackers = new String[serials.length+1];
- trackers[0] = "Auto";
- for (int i = 0; i < serials.length; i++)
- trackers[i+1] = String.format("%d", serials[i]);
+ if (trackers != null) {
AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
builder_serial.setTitle("Select a tracker");
builder_serial.setItems(trackers,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
+ System.out.printf("select item %d %s\n", item, trackers[item].display);
if (item == 0)
select_tracker(0);
else
- select_tracker(serials[item-1]);
+ select_tracker(trackers[item].serial);
}
});
AlertDialog alert_serial = builder_serial.create();
}
return true;
case R.id.delete_track:
- if (serials != null) {
- String[] trackers = new String[serials.length];
- for (int i = 0; i < serials.length; i++)
- trackers[i] = String.format("%d", serials[i]);
+ if (trackers != null) {
AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
builder_serial.setTitle("Delete a track");
- builder_serial.setItems(trackers,
+ final Tracker[] my_trackers = new Tracker[trackers.length - 1];
+ for (int i = 0; i < trackers.length - 1; i++)
+ my_trackers[i] = trackers[i+1];
+ builder_serial.setItems(my_trackers,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
- delete_track(serials[item]);
+ delete_track(my_trackers[item].serial);
}
});
AlertDialog alert_serial = builder_serial.create();
AltosDebug.debug("Location changed to %f,%f",
location.getLatitude(),
location.getLongitude());
- update_ui(telemetry_state, saved_state);
+ update_ui(telemetry_state, state, false);
}
public void onStatusChanged(String provider, int status, Bundle extras) {