altoslib: Make AltosPreferencesBackend abstract. Add set/put Serializable
authorKeith Packard <keithp@keithp.com>
Thu, 28 Apr 2016 19:29:16 +0000 (12:29 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 28 Apr 2016 19:29:16 +0000 (12:29 -0700)
This lets us add functionality to this directly, such as the new
serializable APIs.

Signed-off-by: Keith Packard <keithp@keithp.com>
altosdroid/res/values/strings.xml
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidLink.java
altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java
altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java
altosdroid/src/org/altusmetrum/AltosDroid/ManageFrequenciesActivity.java
altoslib/AltosFrequency.java
altoslib/AltosLink.java
altoslib/AltosMapLoader.java
altoslib/AltosPreferences.java
altoslib/AltosPreferencesBackend.java
altosuilib/AltosUIPreferencesBackend.java

index 58057ca..4380d62 100644 (file)
        <!-- Idle mode -->
        <string name="idle_mode">Idle Mode</string>
        <string name="set_callsign_label">Callsign</string>
-       <string name="connect_idle">Connect</string>
+       <string name="connect_idle">Monitor</string>
        <string name="disconnect_idle">Disconnect</string>
        <string name="reboot_idle">Reboot</string>
        <string name="igniters_idle">Fire Igniters</string>
index 2b10b11..0fd9af7 100644 (file)
@@ -170,8 +170,8 @@ public abstract class AltosDroidLink extends AltosLink {
                        }
                        buffer_off = 0;
                }
-               if (AltosDebug.D)
-                       debug_input(in_buffer[buffer_off]);
+//             if (AltosDebug.D)
+//                     debug_input(in_buffer[buffer_off]);
                return in_buffer[buffer_off++];
        }
 
@@ -207,7 +207,7 @@ public abstract class AltosDroidLink extends AltosLink {
 
        public void print(String data) {
                byte[] bytes = data.getBytes();
-               AltosDebug.debug(data.replace('\n', '\\'));
+//             AltosDebug.debug(data.replace('\n', '\\'));
                for (byte b : bytes)
                        putchar(b);
        }
index c2db377..5c7ec51 100644 (file)
@@ -26,7 +26,7 @@ import android.util.*;
 
 import org.altusmetrum.altoslib_10.*;
 
-public class AltosDroidPreferencesBackend implements AltosPreferencesBackend {
+public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        public final static String        NAME    = "org.altusmetrum.AltosDroid";
        private Context                   context = null;
        private SharedPreferences         prefs   = null;
index 9e3dac6..931c3cf 100644 (file)
@@ -43,7 +43,6 @@ class IgniterItem {
        public TextView status_view = null;
 
        private void update() {
-               AltosDebug.debug("update item %s %s", pretty, status);
                if (pretty_view != null)
                        pretty_view.setText(pretty);
                if (status_view != null)
@@ -77,7 +76,6 @@ class IgniterItem {
        }
 
        public IgniterItem() {
-               AltosDebug.debug("New igniter item");
        }
 }
 
@@ -102,9 +100,7 @@ class IgniterAdapter extends ArrayAdapter<IgniterItem> {
                        item.realize(igniter_view,
                                     (TextView) igniter_view.findViewById(R.id.igniter_name),
                                     (TextView) igniter_view.findViewById(R.id.igniter_status));
-                       AltosDebug.debug("Realize new igniter view");
-               } else
-                       AltosDebug.debug("Reuse existing igniter view");
+               }
                if (position == selected_item)
                        item.igniter_view.setBackgroundColor(Color.RED);
                else
@@ -123,11 +119,11 @@ public class IgniterActivity extends Activity {
        private IgniterAdapter igniters_adapter;
 
        private boolean is_bound;
-       private boolean timer_running;
        private Messenger service = null;
        private final Messenger messenger = new Messenger(new IncomingHandler(this));
 
-       private Timer timer;
+       private Timer query_timer;
+       private boolean query_timer_running;
 
        private Timer arm_timer;
        private int arm_remaining;
@@ -156,6 +152,7 @@ public class IgniterActivity extends Activity {
        private ServiceConnection connection = new ServiceConnection() {
                public void onServiceConnected(ComponentName className, IBinder binder) {
                        service = new Messenger(binder);
+                       query_timer_tick();
                }
 
                public void onServiceDisconnected(ComponentName className) {
@@ -205,12 +202,16 @@ public class IgniterActivity extends Activity {
                        IgniterItem     item = igniters_adapter.getItem(igniters_adapter.selected_item);
                        FireThread      ft = new FireThread(item.name);
                        ft.run();
+                       arm.setChecked(false);
                }
        }
 
        private void arm_igniter(boolean is_checked) {
                if (is_checked) {
+                       arm_timer_stop();
                        arm_timer = new Timer();
+                       arm_remaining = 10;
+                       arm_set_text();
                        fire.setEnabled(true);
                        arm_timer.scheduleAtFixedRate(new TimerTask() {
                                        public void run() {
@@ -218,22 +219,37 @@ public class IgniterActivity extends Activity {
                                        }},
                                1000L, 1000L);
                } else {
-                       arm_timer.cancel();
+                       arm_timer_stop();
                        fire.setEnabled(false);
                }
        }
 
-       private synchronized void timer_tick() {
-               if (timer_running)
+       private synchronized void query_timer_tick() {
+               if (query_timer_running)
                        return;
-               timer_running = true;
-               try {
-                       Message msg = Message.obtain(null, TelemetryService.MSG_IGNITER_QUERY);
-                       msg.replyTo = messenger;
-                       service.send(msg);
-               } catch (RemoteException re) {
-                       timer_running = false;
-               }
+               if (service == null)
+                       return;
+               query_timer_running = true;
+               Thread thread = new Thread(new Runnable() {
+                               public void run() {
+                                       try {
+                                               Message msg = Message.obtain(null, TelemetryService.MSG_IGNITER_QUERY);
+                                               msg.replyTo = messenger;
+                                               if (service == null) {
+                                                       synchronized(IgniterActivity.this) {
+                                                               query_timer_running = false;
+                                                       }
+                                               } else
+                                                       service.send(msg);
+                                       } catch (RemoteException re) {
+                                               AltosDebug.debug("igniter query thread failed");
+                                               synchronized(IgniterActivity.this) {
+                                                       query_timer_running = false;
+                                               }
+                                       }
+                               }
+                       });
+               thread.start();
        }
 
        private boolean set_igniter(HashMap <String,Integer> status, String name, String pretty) {
@@ -253,7 +269,7 @@ public class IgniterActivity extends Activity {
        }
 
        private synchronized void igniter_status(HashMap <String,Integer> status) {
-               timer_running = false;
+               query_timer_running = false;
                if (status == null) {
                        AltosDebug.debug("no igniter status");
                        return;
@@ -266,24 +282,41 @@ public class IgniterActivity extends Activity {
                        if (!set_igniter(status, name, pretty))
                                break;
                }
-//             if (igniters_adapter.selected_item >= 0)
-//                     igniters_view.setSelection(selected_item);
+       }
+
+       private synchronized void arm_timer_stop() {
+               if (arm_timer != null) {
+                       arm_timer.cancel();
+                       arm_timer = null;
+               }
+               arm_remaining = 0;
        }
 
        private void arm_set_text() {
                String  text = String.format("Armed %d", arm_remaining);
 
+               if (arm.isChecked())
+                       arm.setText(text);
                arm.setTextOn(text);
        }
 
        private void arm_timer_tick() {
                --arm_remaining;
                if (arm_remaining <= 0) {
-                       timer.cancel();
-                       arm.setChecked(false);
-                       fire.setEnabled(false);
-               } else
-                       arm_set_text();
+                       arm_timer_stop();
+                       runOnUiThread(new Runnable() {
+                                       public void run() {
+                                               arm.setChecked(false);
+                                               fire.setEnabled(false);
+                                       }
+                               });
+               } else {
+                       runOnUiThread(new Runnable() {
+                                       public void run() {
+                                               arm_set_text();
+                                       }
+                               });
+               }
        }
 
        private void select_item(int position) {
@@ -293,8 +326,6 @@ public class IgniterActivity extends Activity {
                        if (position >= 0) {
                                igniters_view.setItemChecked(position, true);
                                arm.setEnabled(true);
-                               arm_remaining = 10;
-                               arm_set_text();
                        } else
                                arm.setEnabled(false);
                        igniters_adapter.selected_item = position;
@@ -304,6 +335,7 @@ public class IgniterActivity extends Activity {
        private class IgniterItemClickListener implements ListView.OnItemClickListener {
                @Override
                public void onItemClick(AdapterView<?> av, View v, int position, long id) {
+                       AltosDebug.debug("select %d\n", position);
                        select_item(position);
                }
        }
@@ -325,6 +357,7 @@ public class IgniterActivity extends Activity {
                igniters_view.setOnItemClickListener(new IgniterItemClickListener());
 
                fire = (Button) findViewById(R.id.igniter_fire);
+               fire.setEnabled(false);
                fire.setOnClickListener(new OnClickListener() {
                                public void onClick(View v) {
                                        fire_igniter();
@@ -352,19 +385,24 @@ public class IgniterActivity extends Activity {
        @Override
        protected void onResume() {
                super.onResume();
-               timer = new Timer(true);
-               timer.scheduleAtFixedRate(new TimerTask() {
+               query_timer = new Timer(true);
+               query_timer.scheduleAtFixedRate(new TimerTask() {
                                public void run() {
-                                       timer_tick();
+                                       query_timer_tick();
                                }},
-                       1000L, 1000L);
+                       0L, 5000L);
        }
 
        @Override
        protected void onPause() {
                super.onPause();
-               timer.cancel();
-               timer = null;
+               if (query_timer != null) {
+                       query_timer.cancel();
+                       query_timer = null;
+               }
+               arm_timer_stop();
+               arm.setChecked(false);
+               fire.setEnabled(false);
        }
 
        @Override
index 172c44f..401cdc9 100644 (file)
@@ -28,6 +28,7 @@ import android.graphics.*;
 import android.os.*;
 import android.view.*;
 import android.view.View.*;
+import android.view.inputmethod.*;
 import android.widget.*;
 import android.widget.AdapterView.*;
 
@@ -186,6 +187,13 @@ public class ManageFrequenciesActivity extends Activity {
                }
        }
 
+       private void hide_keyboard() {
+               InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
+               View view = getCurrentFocus();
+               if (view != null)
+                       imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+       }
+
        private void set() {
                String  frequency_text = set_frequency.getEditableText().toString();
                String  description_text = set_description.getEditableText().toString();
@@ -199,6 +207,7 @@ public class ManageFrequenciesActivity extends Activity {
                        changed = true;
                } catch (ParseException pe) {
                }
+               hide_keyboard();
        }
 
        private void remove() {
index 80e0d72..9542fe3 100644 (file)
 
 package org.altusmetrum.altoslib_10;
 
-public class AltosFrequency {
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+public class AltosFrequency implements Serializable {
        public double   frequency;
        public String   description;
 
index 73bab3e..cd8609c 100644 (file)
@@ -170,8 +170,8 @@ public abstract class AltosLink implements Runnable {
                boolean can_cancel = can_cancel_reply();
                String  reply = null;
 
-               if (!can_cancel && remote)
-                       System.out.printf("Uh-oh, reading remote serial device from swing thread\n");
+//             if (!can_cancel && remote)
+//                     System.out.printf("Uh-oh, reading remote serial device from swing thread\n");
 
                if (remote && can_cancel) {
                        timeout = 500;
index 9d4059e..15fd756 100644 (file)
@@ -88,7 +88,6 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen
 
                for (int y = (int) upper_left.y; y <= lower_right.y; y += AltosMap.px_size) {
                        for (int x = (int) upper_left.x; x <= lower_right.x; x += AltosMap.px_size) {
-                               listener.debug("Make tile at %d, %d\n", x, y);
                                AltosPointInt   point = new AltosPointInt(x, y);
                                AltosLatLon     ul = transform.lat_lon(point);
                                AltosLatLon     center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
@@ -174,7 +173,6 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen
 
                ++tiles_loaded_total;
                ++tiles_loaded_layer;
-               listener.debug("total %d layer %d\n", tiles_loaded_total, tiles_loaded_layer);
 
                if (tiles_loaded_layer == tiles_this_layer) {
                        ++layers_loaded;
index 4bf48f6..cc340d0 100644 (file)
@@ -116,6 +116,7 @@ public class AltosPreferences {
        public final static String      frequency_count = "COUNT";
        public final static String      frequency_format = "FREQUENCY-%d";
        public final static String      description_format = "DESCRIPTION-%d";
+       public final static String      frequenciesPreference = "FREQUENCIES";
 
        /* Units preference */
 
@@ -132,24 +133,29 @@ public class AltosPreferences {
        static int      map_type;
 
        public static AltosFrequency[] load_common_frequencies() {
+
                AltosFrequency[] frequencies = null;
-               boolean existing = false;
-               existing = backend.nodeExists(common_frequencies_node_name);
 
-               if (existing) {
-                       AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
-                       int             count = node.getInt(frequency_count, 0);
+               frequencies = (AltosFrequency[]) backend.getSerializable(frequenciesPreference, null);
+
+               if (frequencies == null) {
+                       if (backend.nodeExists(common_frequencies_node_name)) {
+                               AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
+                               int             count = node.getInt(frequency_count, 0);
 
-                       frequencies = new AltosFrequency[count];
-                       for (int i = 0; i < count; i++) {
-                               double  frequency;
-                               String  description;
+                               frequencies = new AltosFrequency[count];
+                               for (int i = 0; i < count; i++) {
+                                       double  frequency;
+                                       String  description;
 
-                               frequency = node.getDouble(String.format(frequency_format, i), 0.0);
-                               description = node.getString(String.format(description_format, i), null);
-                               frequencies[i] = new AltosFrequency(frequency, description);
+                                       frequency = node.getDouble(String.format(frequency_format, i), 0.0);
+                                       description = node.getString(String.format(description_format, i), null);
+                                       frequencies[i] = new AltosFrequency(frequency, description);
+                               }
                        }
-               } else {
+               }
+
+               if (frequencies == null) {
                        frequencies = new AltosFrequency[10];
                        for (int i = 0; i < 10; i++) {
                                frequencies[i] = new AltosFrequency(434.550 + i * .1,
@@ -159,15 +165,6 @@ public class AltosPreferences {
                return frequencies;
        }
 
-       public static void save_common_frequencies(AltosFrequency[] frequencies) {
-               AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
-
-               node.putInt(frequency_count, frequencies.length);
-               for (int i = 0; i < frequencies.length; i++) {
-                       node.putDouble(String.format(frequency_format, i), frequencies[i].frequency);
-                       node.putString(String.format(description_format, i), frequencies[i].description);
-               }
-       }
        public static int launcher_serial;
 
        public static int launcher_channel;
@@ -355,28 +352,10 @@ public class AltosPreferences {
 
        public static void set_state(int serial, AltosState state, AltosListenerState listener_state) {
 
-               backend.debug("set_state for %d pos %g,%g\n",
-                             serial,
-                             state.gps != null ? state.gps.lat : 0.0,
-                             state.gps != null ? state.gps.lon : 0.0);
-
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
-               try {
-                       ObjectOutputStream oos = new ObjectOutputStream(baos);
-
-                       AltosSavedState saved_state = new AltosSavedState(state, listener_state);
-                       oos.writeObject(saved_state);
-
-                       byte[] bytes = baos.toByteArray();
-
-                       synchronized(backend) {
-                               backend.putBytes(String.format(statePreferenceFormat, serial), bytes);
-                               backend.putInt(statePreferenceLatest, serial);
-                               flush_preferences();
-                       }
-               } catch (IOException ie) {
-                       backend.debug("set_state failed %s\n", ie.toString());
+               synchronized(backend) {
+                       backend.putSerializable(String.format(statePreferenceFormat, serial),
+                                               new AltosSavedState(state, listener_state));
+                       backend.putInt(statePreferenceLatest, serial);
                }
        }
 
@@ -386,7 +365,6 @@ public class AltosPreferences {
 
                for (String key : keys) {
                        if (key.startsWith(statePreferenceHead)) {
-                               backend.debug("list_states %s\n", key);
                                try {
                                        int serial = AltosParse.parse_int(key.substring(statePreferenceHead.length()));
                                        states.add(serial);
@@ -412,35 +390,9 @@ public class AltosPreferences {
        }
 
        public static AltosSavedState state(int serial) {
-               byte[] bytes = null;
-
-               backend.debug("get state %d\n", serial);
-
                synchronized(backend) {
-                       bytes = backend.getBytes(String.format(statePreferenceFormat, serial), null);
-               }
-
-               if (bytes == null) {
-                       backend.debug("no state for %d\n", serial);
-                       return null;
-               }
-
-               ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-               try {
-                       ObjectInputStream ois = new ObjectInputStream(bais);
-                       AltosSavedState saved_state = (AltosSavedState) ois.readObject();
-                       backend.debug("got saved state for %d: %g,%g\n",
-                                     serial,
-                                     saved_state.state.gps != null ? saved_state.state.gps.lat : 0.0,
-                                     saved_state.state.gps != null ? saved_state.state.gps.lon : 0.0);
-                       return saved_state;
-               } catch (IOException ie) {
-                       backend.debug("IO exception %s\n", ie.toString());
-               } catch (ClassNotFoundException ce) {
-                       backend.debug("ClassNotFoundException %s\n", ce.toString());
+                       return (AltosSavedState) backend.getSerializable(String.format(statePreferenceFormat, serial), null);
                }
-               return null;
        }
 
        public static void set_scanning_telemetry(int new_scanning_telemetry) {
@@ -556,7 +508,7 @@ public class AltosPreferences {
        public static void set_common_frequencies(AltosFrequency[] frequencies) {
                synchronized(backend) {
                        common_frequencies = frequencies;
-                       save_common_frequencies(frequencies);
+                       backend.putSerializable(frequenciesPreference, frequencies);
                        flush_preferences();
                }
        }
index 9f2e8f7..6e1124e 100644 (file)
 
 package org.altusmetrum.altoslib_10;
 
-import java.io.File;
+import java.io.*;
+import java.util.*;
+import java.text.*;
 
-public interface AltosPreferencesBackend {
+public abstract class AltosPreferencesBackend {
 
-       public String  getString(String key, String def);
-       public void    putString(String key, String value);
+       public abstract String  getString(String key, String def);
+       public abstract void    putString(String key, String value);
 
-       public int     getInt(String key, int def);
-       public void    putInt(String key, int value);
+       public abstract int     getInt(String key, int def);
+       public abstract void    putInt(String key, int value);
 
-       public double  getDouble(String key, double def);
-       public void    putDouble(String key, double value);
+       public abstract double  getDouble(String key, double def);
+       public abstract void    putDouble(String key, double value);
 
-       public boolean getBoolean(String key, boolean def);
-       public void    putBoolean(String key, boolean value);
+       public abstract boolean getBoolean(String key, boolean def);
+       public abstract void    putBoolean(String key, boolean value);
 
-       public byte[]  getBytes(String key, byte[] def);
-       public void    putBytes(String key, byte[] value);
+       public abstract byte[]  getBytes(String key, byte[] def);
+       public abstract void    putBytes(String key, byte[] value);
 
-       public boolean nodeExists(String key);
-       public AltosPreferencesBackend node(String key);
+       public Serializable getSerializable(String key, Serializable def) {
+               byte[] bytes = null;
 
-       public String[] keys();
-       public void    remove(String key);
+               bytes = getBytes(key, null);
+               if (bytes == null)
+                       return def;
 
-       public void    flush();
+               ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
 
-       public File homeDirectory();
+               try {
+                       ObjectInputStream ois = new ObjectInputStream(bais);
+                       Serializable object = (Serializable) ois.readObject();
+                       return object;
+               } catch (IOException ie) {
+                       debug("IO exception %s\n", ie.toString());
+               } catch (ClassNotFoundException ce) {
+                       debug("ClassNotFoundException %s\n", ce.toString());
+               }
+               return def;
+       }
 
-       public void debug(String format, Object ... arguments);
+       public void putSerializable(String key, Serializable object) {
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+               try {
+                       ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+                       oos.writeObject(object);
+                       byte[] bytes = baos.toByteArray();
+
+                       putBytes(key, bytes);
+               } catch (IOException ie) {
+                       debug("set_state failed %s\n", ie.toString());
+               }
+       }
+
+       public abstract boolean nodeExists(String key);
+       public abstract AltosPreferencesBackend node(String key);
+
+       public abstract String[] keys();
+       public abstract void    remove(String key);
+
+       public abstract void    flush();
+
+       public abstract File homeDirectory();
+
+       public abstract void debug(String format, Object ... arguments);
 }
index 9d3f15a..d232edf 100644 (file)
@@ -22,7 +22,7 @@ import java.util.prefs.*;
 import org.altusmetrum.altoslib_10.*;
 import javax.swing.filechooser.FileSystemView;
 
-public class AltosUIPreferencesBackend implements AltosPreferencesBackend {
+public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
 
        private Preferences _preferences = null;