Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
authorBdale Garbee <bdale@gag.com>
Wed, 3 Nov 2021 19:24:41 +0000 (13:24 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 3 Nov 2021 19:24:41 +0000 (13:24 -0600)
21 files changed:
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDebug.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroidPreferencesBackend.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroidTab.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosMapOffline.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TabPad.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TabsAdapter.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TelemetryLogger.java
altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/TelemetryService.java
altoslib/AltosLog.java
altoslib/AltosLogTrace.java [new file with mode: 0644]
altoslib/Makefile.am
configure.ac
doc/Makefile.am
doc/easymini-release-notes.inc
doc/release-notes-1.9.10.inc [new file with mode: 0644]
doc/release-notes.inc
doc/telegps-release-notes.inc
libaltos/Makefile.am
libaltos/libaltos_windows.c
src/telemega-v5.0/.gitignore [new file with mode: 0644]

index 469ec50abfd92c33c3e90aacd2aba542511be738..b2bfeb214caf88723dab31e81d34c714030fc545 100644 (file)
@@ -56,11 +56,14 @@ public class AltosDebug {
                Log.e(TAG, String.format(format, arguments));
        }
 
+       static void trace(String format, Object ... arguments) {
+               error(format, arguments);
+               for (StackTraceElement el : Thread.currentThread().getStackTrace())
+                       Log.e(TAG, "\t" + el.toString() + "\n");
+       }
+
        static void check_ui(String format, Object ... arguments) {
-               if (Looper.myLooper() == Looper.getMainLooper()) {
-                       Log.e(TAG, String.format("ON UI THREAD " + format, arguments));
-                       for (StackTraceElement el : Thread.currentThread().getStackTrace())
-                               Log.e(TAG, "\t" + el.toString() + "\n");
-               }
+               if (Looper.myLooper() == Looper.getMainLooper())
+                       trace("ON UI THREAD " + format, arguments);
        }
 }
index 5caee5f87aab5323ea0032cf54f865649ff22a8b..05a023acde3d60f51d27b3caddc1043291336b3c 100644 (file)
@@ -20,6 +20,7 @@ package org.altusmetrum.AltosDroid;
 
 import java.lang.ref.WeakReference;
 import java.util.*;
+import java.io.*;
 
 import android.Manifest;
 import android.app.Activity;
@@ -86,6 +87,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
        public static final int MSG_UPDATE_AGE      = 2;
        public static final int MSG_IDLE_MODE       = 3;
        public static final int MSG_IGNITER_STATUS  = 4;
+       public static final int MSG_FILE_FAILED     = 5;
 
        // Intent request codes
        public static final int REQUEST_CONNECT_DEVICE = 1;
@@ -190,19 +192,23 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                ad.idle_mode = (Boolean) msg.obj;
                                ad.update_state(null);
                                break;
+                       case MSG_FILE_FAILED:
+                               ad.file_failed((File) msg.obj);
+                               break;
                        }
                }
        };
 
-
        private ServiceConnection mConnection = new ServiceConnection() {
                public void onServiceConnected(ComponentName className, IBinder service) {
+                       AltosDebug.debug("onServiceConnected\n");
                        mService = new Messenger(service);
                        try {
                                Message msg = Message.obtain(null, TelemetryService.MSG_REGISTER_CLIENT);
                                msg.replyTo = mMessenger;
                                mService.send(msg);
                        } catch (RemoteException e) {
+                               AltosDebug.debug("attempt to register telemetry service client failed\n");
                                // In this case the service has crashed before we could even do anything with it
                        }
                        if (pending_usb_device != null) {
@@ -215,17 +221,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
 
                public void onServiceDisconnected(ComponentName className) {
+                       AltosDebug.debug("onServiceDisconnected\n");
                        // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
                        mService = null;
                }
        };
 
        void doBindService() {
+               AltosDebug.debug("doBindService\n");
                bindService(new Intent(this, TelemetryService.class), mConnection, Context.BIND_AUTO_CREATE);
                mIsBound = true;
        }
 
        void doUnbindService() {
+               AltosDebug.debug("doUnbindService\n");
                if (mIsBound) {
                        // If we have received the service, and hence registered with it, then now is the time to unregister.
                        if (mService != null) {
@@ -243,6 +252,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
        }
 
+       public AltosDroidTab findTab(String name) {
+               for (AltosDroidTab mTab : mTabs)
+                       if (name.equals(mTab.tab_name()))
+                               return mTab;
+               return null;
+       }
+
        public void registerTab(AltosDroidTab mTab) {
                mTabs.add(mTab);
        }
@@ -436,6 +452,12 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        void update_ui(TelemetryState telem_state, AltosState state, boolean quiet) {
 
+               AltosDebug.debug("update_ui telem %b state %b quiet %b saved_state %b\n",
+                                telem_state != null,
+                                state != null,
+                                quiet,
+                                saved_state != null);
+
                this.state = state;
 
                int prev_state = AltosLib.ao_flight_invalid;
@@ -525,8 +547,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        saved_state = new SavedState(state);
                }
 
-               for (AltosDroidTab mTab : mTabs)
+               for (AltosDroidTab mTab : mTabs) {
+                       AltosDebug.debug("mTab %s current %s\n",
+                                        mTab, mTabsAdapter.currentItem());
                        mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
+               }
 
                if (mAltosVoice != null && mTabsAdapter.currentItem() != null)
                        mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet);
@@ -589,13 +614,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        @Override
        public void onCreate(Bundle savedInstanceState) {
+               AltosDebug.init(this);
+               AltosDebug.debug("+++ ON CREATE +++");
+
                // Initialise preferences
                AltosDroidPreferences.init(this);
                setTheme(themes[AltosDroidPreferences.font_size()]);
                super.onCreate(savedInstanceState);
-               AltosDebug.init(this);
-               AltosDebug.debug("+++ ON CREATE +++");
-
 
                fm = getSupportFragmentManager();
 
@@ -611,10 +636,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
                mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
 
-               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_pad_name).setIndicator(create_tab_view("Pad")), TabPad.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_flight_name).setIndicator(create_tab_view("Flight")), TabFlight.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_recover_name).setIndicator(create_tab_view("Recover")), TabRecover.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_map_name).setIndicator(create_tab_view("Map")), TabMap.class, null);
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_pad_name).setIndicator(create_tab_view("Pad")), TabPad.class, null, findTab(tab_pad_name));
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_flight_name).setIndicator(create_tab_view("Flight")), TabFlight.class, null, findTab(tab_flight_name));
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_recover_name).setIndicator(create_tab_view("Recover")), TabRecover.class, null, findTab(tab_recover_name));
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_map_name).setIndicator(create_tab_view("Map")), TabMap.class, null, findTab(tab_map_name));
 
                // Display the Version
                mVersion = (TextView) findViewById(R.id.version);
@@ -735,11 +760,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
        @Override
        public void onNewIntent(Intent intent) {
                super.onNewIntent(intent);
-               AltosDebug.debug("onNewIntent");
+               AltosDebug.debug("+ ON NEW INTENT +");
                noticeIntent(intent);
        }
 
-       private void enable_location_updates() {
+       private void enable_location_updates(boolean do_update) {
                // Listen for GPS and Network position updates
                LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 
@@ -760,7 +785,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        AltosDebug.debug("Failed to get GPS updates\n");
                }
 
-               update_ui(telemetry_state, state, true);
+               if (do_update)
+                       update_ui(telemetry_state, state, true);
        }
 
        static final int MY_PERMISSION_REQUEST = 1001;
@@ -784,7 +810,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                                        if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
                                                have_location_permission = true;
-                                               enable_location_updates();
+                                               enable_location_updates(true);
                                                if (map_online != null)
                                                        map_online.position_permission();
                                        }
@@ -798,9 +824,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        @Override
        public void onResume() {
-               super.onResume();
                AltosDebug.debug("+ ON RESUME +");
 
+               super.onResume();
+
                if (!asked_permission) {
                        asked_permission = true;
                        if (ActivityCompat.checkSelfPermission(this,
@@ -828,13 +855,15 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                        }
                }
                if (have_location_permission)
-                       enable_location_updates();
+                       enable_location_updates(false);
        }
 
        @Override
        public void onPause() {
-               super.onPause();
                AltosDebug.debug("- ON PAUSE -");
+
+               super.onPause();
+
                // Stop listening for location updates
                if (have_location_permission)
                        ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
@@ -842,15 +871,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
 
        @Override
        public void onStop() {
-               super.onStop();
                AltosDebug.debug("-- ON STOP --");
+
+               super.onStop();
        }
 
        @Override
        public void onDestroy() {
-               super.onDestroy();
                AltosDebug.debug("--- ON DESTROY ---");
 
+               super.onDestroy();
+
+               saved_state = null;
+
                doUnbindService();
                if (mAltosVoice != null) {
                        mAltosVoice.stop();
@@ -1010,6 +1043,24 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,
                }
        }
 
+       boolean fail_shown;
+
+       private void file_failed(File file) {
+               if (!fail_shown) {
+                       fail_shown = true;
+                       AlertDialog fail = new AlertDialog.Builder(this).create();
+                       fail.setTitle("Failed to Create Log File");
+                       fail.setMessage(file.getPath());
+                       fail.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
+                                      new DialogInterface.OnClickListener() {
+                                              public void onClick(DialogInterface dialog, int which) {
+                                                      dialog.dismiss();
+                                              }
+                                      });
+                       fail.show();
+               }
+       }
+
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                MenuInflater inflater = getMenuInflater();
index 5d836f5dceeb7f21f9711b0c77beffadfe5fadbc..170353ab4838098035f6e1dc37768bb0ee41f9f4 100644 (file)
@@ -78,15 +78,18 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
 
        public String getString(String key, String def) {
                String  ret;
-               ret = prefs.getString(key, def);
-//             AltosDebug.debug("AltosDroidPreferencesBackend get string %s:\n", key);
-//             if (ret == null)
-//                     AltosDebug.debug("      (null)\n");
-//             else {
-//                     String[] lines = ret.split("\n");
-//                     for (String l : lines)
-//                             AltosDebug.debug("        %s\n", l);
-//             }
+               if (key.equals(AltosPreferences.logdirPreference))
+                       ret = null;
+               else
+                       ret = prefs.getString(key, def);
+               AltosDebug.debug("AltosDroidPreferencesBackend get string %s:\n", key);
+               if (ret == null)
+                       AltosDebug.debug("      (null)\n");
+               else {
+                       String[] lines = ret.split("\n");
+                       for (String l : lines)
+                               AltosDebug.debug("        %s\n", l);
+               }
                return ret;
        }
 
@@ -135,7 +138,7 @@ public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
        }
 
        public File homeDirectory() {
-               return Environment.getExternalStorageDirectory();
+               return context.getExternalMediaDirs()[0];
        }
 
        public void debug(String format, Object ... arguments) {
index e6923c376643b245f2592a50d1bc75fe7ac0f419..f79c88e6c00b90aad1f8e17318d2f8cf9d4ffa44 100644 (file)
@@ -68,6 +68,7 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen
 
        @Override
        public void onAttach(Context context) {
+               AltosDebug.debug("tab onAttach %s %s\n", tab_name(), this);
                super.onAttach(context);
                altos_droid = (AltosDroid) context;
                altos_droid.registerTab(this);
@@ -75,6 +76,7 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen
 
        @Override
        public void onDetach() {
+               AltosDebug.debug("tab onDetach %s %s\n", tab_name(), this);
                super.onDetach();
                altos_droid.unregisterTab(this);
                altos_droid = null;
@@ -83,13 +85,14 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen
        @Override
        public void onResume() {
                super.onResume();
-               AltosDebug.debug("onResume tab %s\n", tab_name());
+               AltosDebug.debug("onResume tab %s %s\n", tab_name(), this);
                set_visible(true);
        }
 
        public void update_ui(TelemetryState telem_state, AltosState state,
                              AltosGreatCircle from_receiver, Location receiver, boolean is_current)
        {
+               AltosDebug.debug("update_ui %s is_current %b\n", tab_name(), is_current);
                last_telem_state = telem_state;
                last_state = state;
                last_from_receiver = from_receiver;
index 60c209e105cf22fee5cb891be1d008c5cff87657..7bd57a4ca39ebfcd19e44a130c91ef20c15db2a8 100644 (file)
@@ -360,6 +360,10 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal
                        debug("MapView draw without map\n");
                        return;
                }
+               if (map.transform == null) {
+                       debug("MapView draw without transform\n");
+                       return;
+               }
                canvas = view_canvas;
                paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                paint.setStrokeWidth(stroke_width);
index 4a8b3f862b9bbeed9077133fc6e8a5b1b1f84f69..fd997612725530357ab9a593b802835d729c632d 100644 (file)
@@ -67,6 +67,7 @@ public class TabPad extends AltosDroidTab {
 
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+               AltosDebug.debug("TabPad onCreateView\n");
                View v = inflater.inflate(R.layout.tab_pad, container, false);
                battery_voltage_view = (TextView) v.findViewById(R.id.battery_voltage_value);
                battery_lights = new GoNoGoLights((ImageView) v.findViewById(R.id.battery_redled),
@@ -157,12 +158,15 @@ public class TabPad extends AltosDroidTab {
                receiver_latitude_view = (TextView) v.findViewById(R.id.receiver_lat_value);
                receiver_longitude_view = (TextView) v.findViewById(R.id.receiver_lon_value);
                receiver_altitude_view = (TextView) v.findViewById(R.id.receiver_alt_value);
-        return v;
+
+               AltosDebug.debug("TabPad onCreateView done battery_voltage_view %s\n", battery_voltage_view);
+               return v;
        }
 
        public String tab_name() { return AltosDroid.tab_pad_name; }
 
        public void show(TelemetryState telem_state, AltosState state, AltosGreatCircle from_receiver, Location receiver) {
+               AltosDebug.debug("pad show state %b bvv %s\n", state != null, battery_voltage_view);
                if (state != null) {
                        battery_voltage_view.setText(AltosDroid.number("%1.2f V", state.battery_voltage));
                        battery_lights.set(state.battery_voltage >= AltosLib.ao_battery_good, state.battery_voltage == AltosLib.MISSING);
@@ -244,8 +248,11 @@ public class TabPad extends AltosDroidTab {
                        double altitude = AltosLib.MISSING;
                        if (receiver.hasAltitude())
                                altitude = receiver.getAltitude();
-                       receiver_latitude_view.setText(AltosDroid.pos(receiver.getLatitude(), "N", "S"));
-                       receiver_longitude_view.setText(AltosDroid.pos(receiver.getLongitude(), "E", "W"));
+                       String lat_text = AltosDroid.pos(receiver.getLatitude(), "N", "S");
+                       String lon_text = AltosDroid.pos(receiver.getLongitude(), "E", "W");
+                       AltosDebug.debug("lat %s lon %s\n", lat_text, lon_text);
+                       receiver_latitude_view.setText(lat_text);
+                       receiver_longitude_view.setText(lon_text);
                        set_value(receiver_altitude_view, AltosConvert.height, 1, altitude);
                }
        }
index 23d365b4492e06c136e3f008eaf6304adde8d759..0878c011d7c3a39c19d5d113b854567ab8fcb250 100644 (file)
@@ -54,10 +54,11 @@ public class TabsAdapter extends FragmentPagerAdapter
                private final Bundle args;
                private Fragment fragment;
 
-               TabInfo(String _tag, Class<?> _class, Bundle _args) {
+               TabInfo(String _tag, Class<?> _class, Bundle _args, Fragment _fragment) {
                        tag = _tag;
                        clss = _class;
                        args = _args;
+                       fragment = _fragment;
                }
        }
 
@@ -86,11 +87,11 @@ public class TabsAdapter extends FragmentPagerAdapter
                mViewPager.addOnPageChangeListener(this);
        }
 
-       public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
+       public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args, Fragment fragment) {
                tabSpec.setContent(new DummyTabFactory(mContext));
                String tag = tabSpec.getTag();
 
-               TabInfo info = new TabInfo(tag, clss, args);
+               TabInfo info = new TabInfo(tag, clss, args, fragment);
                mTabs.add(info);
                mTabHost.addTab(tabSpec);
                notifyDataSetChanged();
@@ -105,7 +106,8 @@ public class TabsAdapter extends FragmentPagerAdapter
        public Fragment getItem(int position) {
                TabInfo info = mTabs.get(position);
                AltosDebug.debug("TabsAdapter.getItem(%d)", position);
-               info.fragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
+               if (info.fragment == null)
+                       info.fragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
                return info.fragment;
        }
 
@@ -121,15 +123,19 @@ public class TabsAdapter extends FragmentPagerAdapter
 
                AltosDroidTab   cur_frag = (AltosDroidTab) mTabs.get(position).fragment;
 
+               AltosDebug.debug("TabsAdapter.onTabChanged(%s) = %d cur %s prev %s", tabId, position, cur_frag, prev_frag);
+
                if (prev_frag != cur_frag) {
                        if (prev_frag != null) {
                                prev_frag.set_visible(false);
                        }
                }
-               if (cur_frag != null) {
+
+               /* This happens when the tab is selected before any of them
+                * have been created, like during rotation
+                */
+               if (cur_frag != null)
                        cur_frag.set_visible(true);
-               }
-               AltosDebug.debug("TabsAdapter.onTabChanged(%s) = %d", tabId, position);
                mViewPager.setCurrentItem(position);
        }
 
index 589e15d07a351d96e6f1d0011521f2726191b758..ae5702b48b87dfa9cca64bcaa443057724b6f5f3 100644 (file)
@@ -1,5 +1,24 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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, 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
 package org.altusmetrum.AltosDroid;
 
+import java.io.*;
+
 import org.altusmetrum.altoslib_14.*;
 
 import android.content.BroadcastReceiver;
@@ -8,15 +27,24 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Environment;
 
-public class TelemetryLogger {
-       private Context   context = null;
+public class TelemetryLogger implements AltosLogTrace {
+       private TelemetryService service = null;
        private AltosLink link    = null;
        private AltosLog  logger  = null;
 
        private BroadcastReceiver mExternalStorageReceiver;
 
-       public TelemetryLogger(Context in_context, AltosLink in_link) {
-               context = in_context;
+       /* AltosLogTrace interface */
+       public void trace(String format, Object ... arguments) {
+               AltosDebug.debug(format, arguments);
+       }
+
+       public void open_failed(File file) {
+               service.send_file_failed_to_clients(file);
+       }
+
+       public TelemetryLogger(TelemetryService in_service, AltosLink in_link) {
+               service = in_service;
                link    = in_link;
 
                startWatchingExternalStorage();
@@ -40,7 +68,7 @@ public class TelemetryLogger {
                if (Environment.MEDIA_MOUNTED.equals(state)) {
                        if (logger == null) {
                                AltosDebug.debug("Starting up Telemetry Logging");
-                               logger = new AltosLog(link);
+                               logger = new AltosLog(link,this);
                        }
                } else {
                        AltosDebug.debug("External Storage not present - stopping");
@@ -58,12 +86,12 @@ public class TelemetryLogger {
                IntentFilter filter = new IntentFilter();
                filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
                filter.addAction(Intent.ACTION_MEDIA_REMOVED);
-               context.registerReceiver(mExternalStorageReceiver, filter);
+               service.registerReceiver(mExternalStorageReceiver, filter);
                handleExternalStorageState();
        }
 
        void stopWatchingExternalStorage() {
-               context.unregisterReceiver(mExternalStorageReceiver);
+               service.unregisterReceiver(mExternalStorageReceiver);
        }
 
 }
index 2c2095df68186847225e4480993754123be524a2..b0b82ab9c9673643f8fead134a8a9e9445a8a1d8 100644 (file)
@@ -20,6 +20,7 @@ package org.altusmetrum.AltosDroid;
 
 import java.lang.ref.WeakReference;
 import java.util.concurrent.TimeoutException;
+import java.io.*;
 import java.util.*;
 
 import android.app.*;
@@ -340,6 +341,21 @@ public class TelemetryService extends Service implements AltosIdleMonitorListene
                        send_idle_mode_to_client(client);
        }
 
+       private void send_file_failed_to_client(Messenger client, File f) {
+               Message m = Message.obtain(null, AltosDroid.MSG_FILE_FAILED, f);
+               try {
+                       client.send(m);
+               } catch (RemoteException e) {
+                       AltosDebug.error("Client %s disappeared", client.toString());
+                       remove_client(client);
+               }
+       }
+
+       public void send_file_failed_to_clients(File f) {
+               for (Messenger client : clients)
+                       send_file_failed_to_client(client, f);
+       }
+
        private void telemetry_start() {
                if (telemetry_reader == null && idle_monitor == null && !ignite_running) {
                        telemetry_reader = new TelemetryReader(altos_link, handler);
index 7065614b21c50f52a5f59eca71dc691084282c03..7dc9fd4c4ae2621210ad694ff879f92998448a8d 100644 (file)
@@ -37,6 +37,12 @@ public class AltosLog implements Runnable {
        Thread                          log_thread;
        AltosFile                       file;
        AltosLink                       link;
+       AltosLogTrace                   trace;
+
+       private void trace(String format, Object ... arguments) {
+               if (trace != null)
+                       trace.trace(format, arguments);
+       }
 
        private void close_log_file() {
                if (log_file != null) {
@@ -62,10 +68,25 @@ public class AltosLog implements Runnable {
        }
 
        boolean open (AltosCalData cal_data) throws IOException, InterruptedException {
+               trace("open serial %d flight %d receiver_serial %d",
+                     cal_data.serial,
+                     cal_data.flight,
+                     cal_data.receiver_serial);
+
                AltosFile       a = new AltosFile(cal_data);
 
-               log_file = new FileWriter(a, true);
+               trace("open file %s\n", a.getPath());
+
+               try {
+                       log_file = new FileWriter(a, true);
+               } catch (IOException ie) {
+                       log_file = null;
+                       trace("open file failed\n");
+                       if (trace != null)
+                               trace.open_failed(a);
+               }
                if (log_file != null) {
+                       trace("open file success\n");
                        while (!pending_queue.isEmpty()) {
                                String s = pending_queue.take();
                                log_file.write(s);
@@ -79,6 +100,7 @@ public class AltosLog implements Runnable {
        }
 
        public void run () {
+               trace("log run start\n");
                try {
                        AltosConfigData receiver_config = link.config_data();
                        AltosCalData    cal_data = new AltosCalData();
@@ -117,21 +139,30 @@ public class AltosLog implements Runnable {
                                        pending_queue.put(line.line);
                        }
                } catch (InterruptedException ie) {
+                       trace("interrupted exception\n");
                } catch (TimeoutException te) {
+                       trace("timeout exception\n");
                } catch (IOException ie) {
+                       trace("io exception %s message %s\n", ie.toString(), ie.getMessage());
                }
+               trace("log run done\n");
                close();
        }
 
-       public AltosLog (AltosLink link) {
+       public AltosLog (AltosLink link, AltosLogTrace trace) {
                pending_queue = new LinkedBlockingQueue<String> ();
                input_queue = new LinkedBlockingQueue<AltosLine> ();
                link.add_monitor(input_queue);
                serial = -1;
                flight = -1;
+               this.trace = trace;
                this.link = link;
                log_file = null;
                log_thread = new Thread(this);
                log_thread.start();
        }
+
+       public AltosLog (AltosLink link) {
+               this(link, null);
+       }
 }
diff --git a/altoslib/AltosLogTrace.java b/altoslib/AltosLogTrace.java
new file mode 100644 (file)
index 0000000..64b41d6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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; 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_14;
+
+import java.io.*;
+import java.net.*;
+
+public interface AltosLogTrace {
+       public abstract void trace(String format, Object ... arguments);
+
+       public abstract void open_failed(File path);
+}
index 39e287fa457f4c2a1473cc64448f5bfd99bce54e..21651ef910ac73b93580396e173ed9d7f2c387d3 100644 (file)
@@ -87,6 +87,7 @@ altoslib_JAVA = \
        AltosLink.java \
        AltosListenerState.java \
        AltosLog.java \
+       AltosLogTrace.java \
        AltosMag.java \
        AltosMma655x.java \
        AltosMs5607.java \
index 71a334b2eb2ed86fc8b70a3def48e8c262c0de65..2bf21751b1e0042a938c6363368cc8e2bc0807c7 100644 (file)
@@ -18,13 +18,13 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.9)
-ANDROID_VERSION=31
+AC_INIT([altos], 1.9.10.1)
+ANDROID_VERSION=33
 AC_CONFIG_SRCDIR([src/kernel/ao.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 
-RELEASE_DATE=2021-10-06
+RELEASE_DATE=2021-10-16
 AC_SUBST(RELEASE_DATE)
 
 DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
index 52c408e367ecec5dde92f1ced747ecf190f6c5e1..d7d92f2cbf76841647ffccda29882b128b4fd77d 100644 (file)
@@ -17,6 +17,7 @@ FAKETIME=TZ=UTC faketime -f '$(RELEASE_DATE) 00:00:00 i0'
 endif
 
 RELNOTES_INC=\
+       release-notes-1.9.10.inc \
        release-notes-1.9.9.inc \
        release-notes-1.9.8.inc \
        release-notes-1.9.7.inc \
index a1b4415a9985ebfa38f7a85c66309c367b1e7dde..34e6471a2e138b5d2e6f97a8e9b934ca09615484 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.10.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.9.adoc[]
 
diff --git a/doc/release-notes-1.9.10.inc b/doc/release-notes-1.9.10.inc
new file mode 100644 (file)
index 0000000..0c91a69
--- /dev/null
@@ -0,0 +1,21 @@
+= Release Notes for Version 1.9.10
+include::release-head.adoc[]
+:doctype: article
+
+       Version 1.9.10
+
+       This release contains a couple of bug fixes for ground station software.
+
+       == AltosUI
+
+       * Rework the windows DLL build to make AltosUI run on more
+          instances of Windows 10.
+
+       == AltosDroid
+
+       * Adapt to Android security changes which prevent AltosDroid
+         from storing flights in
+         /storage/emulated/0/AltusMetrum. Now, flights are stored in
+         /storage/emulated/0/media/org.altusmetrum.AltosDroid/AltusMetrum
+         instead.  Also, AltosDroid will display an error message if
+         flight data cannot be logged.
index 4a76c96f09e08a4fd7bfa86475b073f24ce4c679..f492981abf3c4f9be7d623c5cb69743c3f40c3a7 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.10.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.9.adoc[]
 
index 90f2e27e0d5947e57414e77e91e3936bedaddc04..dedc6d4a773b6591bf9924a490a37eeb19c90168 100644 (file)
@@ -1,5 +1,9 @@
 [appendix]
 == Release Notes
+       :leveloffset: 2
+       include::release-notes-1.9.10.adoc[]
+
+       <<<<
        :leveloffset: 2
        include::release-notes-1.9.9.adoc[]
 
index 2b9a7aa6b85614a05b542eb8f644b68b1fb06c21..98fa8c11aea7d2e5b60cba1405103f71c6b5cc5a 100644 (file)
@@ -122,10 +122,10 @@ MINGLIBS=-lsetupapi -lws2_32
 fat: all altos.dll altos64.dll
 
 altos.dll: $(WINDOWS_SRC) $(WINDOWS_H)
-       $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+       SOURCE_DATE_EPOCH=0 $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
 
 altos64.dll: $(WINDOWS_SRC) $(WINDOWS_H)
-       $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+       SOURCE_DATE_EPOCH=0 $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
 
 clean-local:
        -rm -rf libaltosJNI *.class *.java classlibaltos.stamp $(SWIG_FILE) libaltos_wrap.c altos.dll altos64.dll
index 33eb77c7ac7c1149f4e03823e8218ca49e399989..f91859ac51e7e3859863965ccaa4b48958f7f5e4 100644 (file)
@@ -59,12 +59,12 @@ log_message(char *fmt, ...)
                char    buffer[4096];
 
                GetLocalTime(&time);
-               sprintf (buffer, "%4d-%02d-%02d %2d:%02d:%02d. ",
+               __ms_sprintf (buffer, "%4d-%02d-%02d %2d:%02d:%02d. ",
                         time.wYear, time.wMonth, time.wDay,
                         time.wHour, time.wMinute, time.wSecond);
                va_start(a, fmt);
 
-               vsprintf(buffer + strlen(buffer), fmt, a);
+               __ms_vsprintf(buffer + strlen(buffer), fmt, a);
                va_end(a);
 
                fputs(buffer, log);
@@ -188,11 +188,11 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
                        if (result != 0) {
                                altos_set_last_windows_error();
                        } else {
-                               sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
+                               __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
                                       "%04X", &vid);
-                               sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
+                               __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
                                       "%04X", &pid);
-                               sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
+                               __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
                                       "%d", &serial);
                        }
                        if (vid == 0 || pid == 0 || serial == 0) {
@@ -201,11 +201,11 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
                                                               instanceid,
                                                               sizeof (instanceid),
                                                               &instanceid_len)) {
-                                       sscanf((char *) instanceid + sizeof("USB\\VID_") - 1,
+                                       __ms_sscanf((char *) instanceid + sizeof("USB\\VID_") - 1,
                                               "%04X", &vid);
-                                       sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_") - 1,
+                                       __ms_sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_") - 1,
                                               "%04X", &pid);
-                                       sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_XXXX\\") - 1,
+                                       __ms_sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_XXXX\\") - 1,
                                               "%d", &serial);
                                } else {
                                        altos_set_last_windows_error();
@@ -667,7 +667,7 @@ static void
 ba2str(BTH_ADDR ba, char *str)
 {
 
-       sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
+       __ms_sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
                get_byte(ba, 0),
                get_byte(ba, 1),
                get_byte(ba, 2),
@@ -681,7 +681,7 @@ str2ba(char *str)
 {
        unsigned int    bytes[6];
 
-       sscanf(str,  "%02x:%02x:%02x:%02x:%02x:%02x",
+       __ms_sscanf(str,  "%02x:%02x:%02x:%02x:%02x:%02x",
               &bytes[0],
               &bytes[1],
               &bytes[2],
diff --git a/src/telemega-v5.0/.gitignore b/src/telemega-v5.0/.gitignore
new file mode 100644 (file)
index 0000000..e67759a
--- /dev/null
@@ -0,0 +1,2 @@
+ao_product.h
+telemega-*.elf