diff --git a/.travis.yml b/.travis.yml index cf65592b2..2234f45de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ deploy: tags: true env: global: + - secure: Vt32deOYoaVrGv/LsrPQ5+O5v0sHz07G4HaEEW2fGwGb5El5K6BddqV8mtBuK681EcohoWv/ySOpuE95lmNu8xldffPY4o0JZE9RQiZAvXhOYec0nv7mg8bscYEffLP2sXpSb9bag5Cf/G76A4QxzvQAbFH3lK6Uy1Phghwwmak= - secure: dmvaay5GzUO1qkaRk46+o96rRmP4cKAvbgD6njgCegfaGbXwDAMQGKjPeJc5uORWpmxnqpqSg8+0ZvYwkUsflvG3tTtsPV+llzjkDGnstvLxFBEU/JibLoUscOdrdkrc6DsxZtfZ9jJWkb271ARjgTxjMHnNcN3jwTLfU67htXc= - secure: Kr9rh1Y7MM1iJ6hS0YO/1ymLfHt+ncsMk4nY2DEO74V2ROTaqWsA1GdtczWb8AD3ZjeF8Qw+wBlaJvZ5Sx51ydGnmT5X/e/pHkKMIe96UHjugvogEigLcw6pI9ZRo/p8A+tZ3WOeY2VVoQhOx6sCObNBIEQE5NVrRpldrTB+D+M= - secure: eBbtEJOTUJ3PaM1xfgW9ccXdiG28TeMGYWfxCW1nBQvtdLzIHyfDZb8FNEFkChaq41sk44+IVMQNLj8tybAPlg3E6SOwLd5SWjhv+0f+tJWYBY1j04MKS8WE3osE3iifs+CafjOk8lws4YH0tKaUXsqqLO/53OuT3px2mlSxjwc= @@ -40,3 +41,5 @@ env: - secure: fSxLsuELLvaNmGtFn4ZtELt8d1gSJZwJ+5+QahpV0b9Nf/JNUehSl4RSYVFsq2uw5fuhdsgy/OujpGEYWTA6iDidaB+YOXfwR3q1vpxwUCIEAjbhVG0TwlFh0wqcYOq8FHUBlSNh9DoLJh61N+Y1pCzoXAPFBqaqQ1wjUpxUfCw= - secure: VHn45y17v68I/VNhIBCNue9eRMdaRurHBSu8cGO3NLcjZFpJqYehqKnwhjIS2eP1SDHEM++LFz6XpANpU4KwdjnYaP5qEU4b2zEVqvc+9GZK37kFIaeSaOrvoRGYVrzp+oeU8ehG6MjsgXWjIwE4QNLVc8dinILjuqWXY5zxqGs= - GRADLE_OPTS="-Xmx1024m -XX:MaxPermSize=1024m" +after_success: + - scripts/push-javadoc.sh \ No newline at end of file diff --git a/build.gradle b/build.gradle index d8e2e6ecc..11eb7d36a 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,10 @@ buildscript { } } +plugins { + id "org.sonarqube" version "2.7" +} + allprojects { repositories { jcenter() diff --git a/enabler/build.gradle b/enabler/build.gradle index fad7c82ce..f240f3158 100644 --- a/enabler/build.gradle +++ b/enabler/build.gradle @@ -77,7 +77,7 @@ android { dependencies { implementation project(":library") - implementation 'com.android.support:support-v4:28.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0-beta01' implementation 'com.bugsnag:bugsnag-android:4.3.2' implementation 'com.microsoft.appcenter:appcenter-analytics:2.3.0' implementation 'com.microsoft.appcenter:appcenter-crashes:2.3.0' diff --git a/enabler/src/androidTest/java/com/openxc/remote/VehicleServiceTest.java b/enabler/src/androidTest/java/com/openxc/remote/VehicleServiceTest.java index 0dc845ccc..874b0afc0 100644 --- a/enabler/src/androidTest/java/com/openxc/remote/VehicleServiceTest.java +++ b/enabler/src/androidTest/java/com/openxc/remote/VehicleServiceTest.java @@ -5,8 +5,7 @@ import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; -public class VehicleServiceTest - extends ServiceTestCase { +public class VehicleServiceTest extends ServiceTestCase { Intent startIntent; public VehicleServiceTest() { diff --git a/enabler/src/androidTest/java/com/openxc/sources/trace/TraceVehicleDataSourceTest.java b/enabler/src/androidTest/java/com/openxc/sources/trace/TraceVehicleDataSourceTest.java index f5c1c9281..ce7bc9466 100644 --- a/enabler/src/androidTest/java/com/openxc/sources/trace/TraceVehicleDataSourceTest.java +++ b/enabler/src/androidTest/java/com/openxc/sources/trace/TraceVehicleDataSourceTest.java @@ -1,111 +1,111 @@ -package com.openxc.sources.trace; - -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.openxc.TestUtils; -import com.openxc.messages.SimpleVehicleMessage; -import com.openxc.messages.VehicleMessage; -import com.openxc.sources.DataSourceException; -import com.openxc.sources.SourceCallback; -import com.openxc.sources.VehicleDataSource; -import com.openxcplatform.enabler.R; - -public class TraceVehicleDataSourceTest extends AndroidTestCase { - URI traceUri; - URI malformedTraceUri; - TraceVehicleDataSource source; - Thread thread; - SourceCallback callback; - boolean receivedNumericalCallback; - boolean receivedBooleanCallback;; - - @Override - protected void setUp() { - traceUri = TestUtils.copyToStorage(getContext(), R.raw.tracejson, - "trace.json"); - malformedTraceUri = TestUtils.copyToStorage(getContext(), - R.raw.tracetxt, "malformed-trace.json"); - callback = new SourceCallback() { - public void receive(VehicleMessage message) { - SimpleVehicleMessage simpleMessage = (SimpleVehicleMessage) message; - if(simpleMessage.getValue().getClass() == Boolean.class) { - receivedBooleanCallback = true; - } else if(simpleMessage.getValue().getClass() == Double.class) { - receivedNumericalCallback = true; - } - } - - public void sourceDisconnected(VehicleDataSource source) { } - - public void sourceConnected(VehicleDataSource source) { } - }; - } - - @Override - protected void tearDown() throws Exception { - if(source != null) { - source.stop(); - } - if(thread != null) { - try { - thread.join(); - } catch(InterruptedException e) {} - } - super.tearDown(); - } - - private void startTrace(TraceVehicleDataSource source) { - thread = new Thread(source); - thread.start(); - try { - Thread.sleep(500); - } catch(InterruptedException e){ } - } - - @SmallTest - public void testPlaybackFile() throws InterruptedException, - DataSourceException { - receivedNumericalCallback = false; - receivedBooleanCallback = false; - source = new TraceVehicleDataSource(callback, getContext(), traceUri); - startTrace(source); - assertTrue(receivedNumericalCallback); - assertTrue(receivedBooleanCallback); - } - - @SmallTest - public void testMalformedJson() throws InterruptedException , - DataSourceException { - receivedNumericalCallback = false; - receivedBooleanCallback = false; - source = new TraceVehicleDataSource(callback, getContext(), - malformedTraceUri); - startTrace(source); - assertFalse(receivedNumericalCallback); - source.stop(); - } - - @SmallTest - public void testMissingFile() throws MalformedURLException, - InterruptedException, DataSourceException, - URISyntaxException { - receivedNumericalCallback = false; - receivedBooleanCallback = false; - source = new TraceVehicleDataSource(callback, getContext(), - new URL("file:///foo").toURI()); - startTrace(source); - assertFalse(receivedNumericalCallback); - } - - @SmallTest - public void testConstructWithCallbackAndFile() - throws DataSourceException { - source = new TraceVehicleDataSource(callback, getContext(), traceUri); - } -} +//package com.openxc.sources.trace; +// +//import java.net.MalformedURLException; +//import java.net.URI; +//import java.net.URISyntaxException; +//import java.net.URL; +// +//import android.test.AndroidTestCase; +//import android.test.suitebuilder.annotation.SmallTest; +// +//import com.openxc.TestUtils; +//import com.openxc.messages.SimpleVehicleMessage; +//import com.openxc.messages.VehicleMessage; +//import com.openxc.sources.DataSourceException; +//import com.openxc.sources.SourceCallback; +//import com.openxc.sources.VehicleDataSource; +//import com.openxcplatform.enabler.R; +// +//public class TraceVehicleDataSourceTest extends AndroidTestCase { +// URI traceUri; +// URI malformedTraceUri; +// TraceVehicleDataSource source; +// Thread thread; +// SourceCallback callback; +// boolean receivedNumericalCallback; +// boolean receivedBooleanCallback;; +// +// @Override +// protected void setUp() { +// traceUri = TestUtils.copyToStorage(getContext(), R.raw.tracejson, +// "trace.json"); +// malformedTraceUri = TestUtils.copyToStorage(getContext(), +// R.raw.tracetxt, "malformed-trace.json"); +// callback = new SourceCallback() { +// public void receive(VehicleMessage message) { +// SimpleVehicleMessage simpleMessage = (SimpleVehicleMessage) message; +// if(simpleMessage.getValue().getClass() == Boolean.class) { +// receivedBooleanCallback = true; +// } else if(simpleMessage.getValue().getClass() == Double.class) { +// receivedNumericalCallback = true; +// } +// } +// +// public void sourceDisconnected(VehicleDataSource source) { } +// +// public void sourceConnected(VehicleDataSource source) { } +// }; +// } +// +// @Override +// protected void tearDown() throws Exception { +// if(source != null) { +// source.stop(); +// } +// if(thread != null) { +// try { +// thread.join(); +// } catch(InterruptedException e) {} +// } +// super.tearDown(); +// } +// +// private void startTrace(TraceVehicleDataSource source) { +// thread = new Thread(source); +// thread.start(); +// try { +// Thread.sleep(500); +// } catch(InterruptedException e){ } +// } +// +// @SmallTest +// public void testPlaybackFile() throws InterruptedException, +// DataSourceException { +// receivedNumericalCallback = false; +// receivedBooleanCallback = false; +// source = new TraceVehicleDataSource(callback, getContext(), traceUri); +// startTrace(source); +// assertTrue(receivedNumericalCallback); +// assertTrue(receivedBooleanCallback); +// } +// +// @SmallTest +// public void testMalformedJson() throws InterruptedException , +// DataSourceException { +// receivedNumericalCallback = false; +// receivedBooleanCallback = false; +// source = new TraceVehicleDataSource(callback, getContext(), +// malformedTraceUri); +// startTrace(source); +// assertFalse(receivedNumericalCallback); +// source.stop(); +// } +// +// @SmallTest +// public void testMissingFile() throws MalformedURLException, +// InterruptedException, DataSourceException, +// URISyntaxException { +// receivedNumericalCallback = false; +// receivedBooleanCallback = false; +// source = new TraceVehicleDataSource(callback, getContext(), +// new URL("file:///foo").toURI()); +// startTrace(source); +// assertFalse(receivedNumericalCallback); +// } +// +// @SmallTest +// public void testConstructWithCallbackAndFile() +// throws DataSourceException { +// source = new TraceVehicleDataSource(callback, getContext(), traceUri); +// } +//} diff --git a/enabler/src/main/java/com/openxc/enabler/CanMessageViewFragment.java b/enabler/src/main/java/com/openxc/enabler/CanMessageViewFragment.java index 0d48012a6..d7414d954 100644 --- a/enabler/src/main/java/com/openxc/enabler/CanMessageViewFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/CanMessageViewFragment.java @@ -7,7 +7,7 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.v4.app.ListFragment; +import androidx.fragment.app.ListFragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; diff --git a/enabler/src/main/java/com/openxc/enabler/DiagnosticRequestFragment.java b/enabler/src/main/java/com/openxc/enabler/DiagnosticRequestFragment.java index 5b54d1c77..8ccaf6a8b 100644 --- a/enabler/src/main/java/com/openxc/enabler/DiagnosticRequestFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/DiagnosticRequestFragment.java @@ -7,7 +7,7 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.v4.app.ListFragment; +import androidx.fragment.app.ListFragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -174,9 +174,11 @@ public void onActivityCreated(Bundle savedInstanceState) { @Override public void onResume() { super.onResume(); - getActivity().bindService( - new Intent(getActivity(), VehicleManager.class), - mConnection, Context.BIND_AUTO_CREATE); + if (getActivity() != null) { + getActivity().bindService( + new Intent(getActivity(), VehicleManager.class), + mConnection, Context.BIND_AUTO_CREATE); + } } @Override diff --git a/enabler/src/main/java/com/openxc/enabler/OpenXcEnablerActivity.java b/enabler/src/main/java/com/openxc/enabler/OpenXcEnablerActivity.java index f41a39476..3ab866754 100644 --- a/enabler/src/main/java/com/openxc/enabler/OpenXcEnablerActivity.java +++ b/enabler/src/main/java/com/openxc/enabler/OpenXcEnablerActivity.java @@ -6,11 +6,11 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -82,7 +82,12 @@ public void onCreate(Bundle savedInstanceState) { @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putInt("tab", mPager.getCurrentItem()); + try { + outState.putInt("tab", mPager.getCurrentItem()); + }catch (NoClassDefFoundError e){ + Log.w(TAG, "Failing to get current page "); + e.printStackTrace(); + } } @Override @@ -159,7 +164,12 @@ static String getBugsnagToken(Context context) { @Override protected void onResume() { super.onResume(); - checkForCrashes(); + try { + checkForCrashes(); + }catch (NoClassDefFoundError e){ + Log.w(TAG, "Failed checkForChrashes call"); + e.printStackTrace(); + } } private void checkForCrashes() { diff --git a/enabler/src/main/java/com/openxc/enabler/SendCanMessageFragment.java b/enabler/src/main/java/com/openxc/enabler/SendCanMessageFragment.java index bd4ce5bf9..1ee43f838 100644 --- a/enabler/src/main/java/com/openxc/enabler/SendCanMessageFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/SendCanMessageFragment.java @@ -6,7 +6,7 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.v4.app.ListFragment; +import androidx.fragment.app.ListFragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -119,9 +119,11 @@ private void onSendCanMessage(Spinner busSpinner, @Override public void onResume() { super.onResume(); - getActivity().bindService( - new Intent(getActivity(), VehicleManager.class), - mConnection, Context.BIND_AUTO_CREATE); + if (getActivity() != null) { + getActivity().bindService( + new Intent(getActivity(), VehicleManager.class), + mConnection, Context.BIND_AUTO_CREATE); + } } @Override diff --git a/enabler/src/main/java/com/openxc/enabler/SendCommandMessageFragment.java b/enabler/src/main/java/com/openxc/enabler/SendCommandMessageFragment.java index b83f914f4..43d4332a8 100644 --- a/enabler/src/main/java/com/openxc/enabler/SendCommandMessageFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/SendCommandMessageFragment.java @@ -6,7 +6,8 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.v4.app.Fragment; +import android.preference.PreferenceManager; +import androidx.fragment.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -19,6 +20,7 @@ import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; +import android.widget.Toast; import com.openxc.VehicleManager; import com.openxc.interfaces.VehicleInterfaceDescriptor; @@ -138,12 +140,17 @@ public void onDisconnected() { getActivity().runOnUiThread(new Runnable() { public void run() { Log.d(TAG, "VI disconnected"); + disconnectAlert(); } }); } } }; - + public void disconnectAlert() { + if (PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getBoolean("isPowerDrop", false)) { + Toast.makeText(getActivity(), "VI Power Dropped", Toast.LENGTH_LONG).show(); + } + } @Override public void onResume() { super.onResume(); diff --git a/enabler/src/main/java/com/openxc/enabler/SettingsActivity.java b/enabler/src/main/java/com/openxc/enabler/SettingsActivity.java index 3f0ea0a48..8de9f6b8f 100644 --- a/enabler/src/main/java/com/openxc/enabler/SettingsActivity.java +++ b/enabler/src/main/java/com/openxc/enabler/SettingsActivity.java @@ -29,8 +29,8 @@ import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.provider.DocumentsContract; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; @@ -64,6 +64,9 @@ public class SettingsActivity extends PreferenceActivity { "com.openxc.enabler.preferences.OUTPUT"; private final static String ABOUT_PREFERENCE = "com.openxc.enabler.preferences.ABOUT"; + private final static String NOTIFICATION_PREFERENCE = + "com.openxc.enabler.preferences.NOTIFICATION"; + private final static int FILE_SELECTOR_RESULT = 100; private static final int APP_PERMISSION_REQUEST_WRITE_STORAGE = 200; @@ -84,6 +87,10 @@ public class SettingsActivity extends PreferenceActivity { private ListPreference mDataFormatListPreference; private CheckBoxPreference mPhoneSensorPreference; + private CheckBoxPreference mpowerDropPreference; + private CheckBoxPreference mnetworkDropPreference; + private CheckBoxPreference musbDropPreference; + private PreferenceCategory mBluetoothPreferences; private PreferenceCategory mNetworkPreferences; private PreferenceCategory mTracePreferences; @@ -143,6 +150,7 @@ protected boolean isValidFragment(String fragmentName){ return RecordingPreferences.class.getName().equals(fragmentName) || OutputPreferences.class.getName().equals(fragmentName) || DataSourcePreferences.class.getName().equals(fragmentName) || + NotificationPreferences.class.getName().equals(fragmentName)|| AboutPreferences.class.getName().equals(fragmentName); } @@ -163,6 +171,9 @@ private void initializeLegacyLayout() { } else if(action.equals(ABOUT_PREFERENCE)) { addPreferencesFromResource(R.xml.about_preferences); initializeAboutPreferences(getPreferenceManager()); + } else if(action.equals(NOTIFICATION_PREFERENCE)) { + addPreferencesFromResource(R.xml.notification_preferences); + //initializeAboutPreferences(getPreferenceManager()); } } else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { addPreferencesFromResource(R.xml.preference_headers_legacy); @@ -311,6 +322,15 @@ public void onCreate(Bundle savedInstanceState) { getPreferenceManager()); } } + public static class NotificationPreferences extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.notification_preferences); + + ((SettingsActivity)getActivity()).initializeNotificationPreferences(getPreferenceManager()); + } + } public static class AboutPreferences extends PreferenceFragment { @Override @@ -345,7 +365,27 @@ protected void initializePhoneSensorPreferences(PreferenceManager manager) { mPhoneSensorClickListener); } + protected void initializeNetworkDropPreferences(PreferenceManager manager) { + mnetworkDropPreference = (CheckBoxPreference) manager.findPreference( + getString(R.string.network_drop_checkbox_key)); + mnetworkDropPreference.setOnPreferenceClickListener( + mNetworkDropClickListener); + + } + protected void initializePowerDropPreferences(PreferenceManager manager) { + mpowerDropPreference = (CheckBoxPreference) manager.findPreference( + getString(R.string.power_drop_checkbox_key)); + mpowerDropPreference.setOnPreferenceClickListener( + mPowerDropClickListener); + + } + protected void initializeUSBDropPreferences(PreferenceManager manager) { + musbDropPreference = (CheckBoxPreference) manager.findPreference( + getString(R.string.usb_drop_checkbox_key)); + musbDropPreference.setOnPreferenceClickListener( + mUSBDropClickListener); + } protected void initializeUploadingPreferences(PreferenceManager manager) { mUploadingPreference = (CheckBoxPreference) manager.findPreference(getString(R.string.uploading_checkbox_key)); mSourceNamePreference = manager.findPreference(getString(R.string.uploading_source_name_key)); @@ -483,6 +523,7 @@ protected void initializeDataSourcePreferences(PreferenceManager manager) { initializePhoneSensorPreferences(manager); initializDataformatPreference(manager); initializeDisableTracePlayingLoopPreferences(manager); + } protected void initializeBluetoothPreferences(PreferenceManager manager) { @@ -538,6 +579,12 @@ protected void initializeNetwork(PreferenceManager manager) { preferences.getString(getString( R.string.network_port_key), null)); } + protected void initializeNotificationPreferences(PreferenceManager manager) { + initializeNetworkDropPreferences(manager); + initializePowerDropPreferences(manager); + initializeUSBDropPreferences(manager); + + } protected void initializeAboutPreferences(PreferenceManager manager) { try { @@ -739,6 +786,39 @@ public boolean onPreferenceClick(Preference preference) { } }; + private Preference.OnPreferenceClickListener mNetworkDropClickListener = + new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + SharedPreferences.Editor editor = pref.edit(); + editor.putBoolean("isNetworkDrop", mnetworkDropPreference.isChecked()); + editor.commit(); + return false; + } + }; + private Preference.OnPreferenceClickListener mPowerDropClickListener = + new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + SharedPreferences.Editor editor = pref.edit(); + editor.putBoolean("isPowerDrop", mpowerDropPreference.isChecked()); + editor.commit(); + return false; + } + }; + + private Preference.OnPreferenceClickListener mUSBDropClickListener = + new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + SharedPreferences.Editor editor = pref.edit(); + editor.putBoolean("isUSBDrop", musbDropPreference.isChecked()); + editor.commit(); + return false; + } + }; + private void checkPhoneSensorPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) diff --git a/enabler/src/main/java/com/openxc/enabler/StatusFragment.java b/enabler/src/main/java/com/openxc/enabler/StatusFragment.java index b0713e169..5bda798f0 100644 --- a/enabler/src/main/java/com/openxc/enabler/StatusFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/StatusFragment.java @@ -1,19 +1,19 @@ package com.openxc.enabler; import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.IBinder; -import android.preference.CheckBoxPreference; -import android.preference.Preference; import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.core.content.ContextCompat; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -39,7 +39,6 @@ import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.app.Activity.RESULT_CANCELED; -import static android.app.Activity.RESULT_OK; public class StatusFragment extends Fragment implements Button.OnClickListener{ public static final int LOCATION_PERMISSION_REQUEST_CODE = 1; @@ -71,7 +70,9 @@ public class StatusFragment extends Fragment implements Button.OnClickListener{ private boolean isTraceRecording; private boolean isDisableTraceLooping; private boolean isStart = false; - + private boolean ispowerDrop; + private boolean isNetworkDrop; + private boolean isUSBDrop; private synchronized void updateViInfo() { if (mVehicleManager != null) { @@ -108,6 +109,8 @@ public void onConnected(final VehicleInterfaceDescriptor descriptor) { } public void onDisconnected() { + disconnectAlertPower(); + if (getActivity() != null) { getActivity().runOnUiThread(new Runnable() { public void run() { @@ -121,6 +124,17 @@ public void run() { } }; + + public void disconnectAlertPower(){ + ispowerDrop = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getBoolean("isPowerDrop", false); + Log.d(TAG,ispowerDrop + "here value"); + if(ispowerDrop){ + Toast.makeText(getActivity(), "VI Power Dropped", Toast.LENGTH_LONG).show(); + } + + } + + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { @@ -189,6 +203,53 @@ public void run() { } }; + private NetworkDisconnectBroadcastReceiver networkDisconnectBroadcastReceiver; + private USBDisconnectBroadcastReceiver usbDisconnectBroadcastReceiver; + + private void registerDisconnectBroadcastReceiver() { + + // Network Disconnect + IntentFilter filter = new IntentFilter(); + filter.addAction(com.openxc.interfaces.network.NetworkVehicleInterface.BROADCAST_NETWORK_DISCONNECTED); + + networkDisconnectBroadcastReceiver = new NetworkDisconnectBroadcastReceiver(); + getContext().registerReceiver(networkDisconnectBroadcastReceiver, filter); + + + // USB Disconnect + IntentFilter usbFilter = new IntentFilter(); + usbFilter.addAction(com.openxc.interfaces.usb.UsbVehicleInterface.BROADCAST_USB_DISCONNECTED); + + usbDisconnectBroadcastReceiver = new USBDisconnectBroadcastReceiver(); + getContext().registerReceiver(usbDisconnectBroadcastReceiver, usbFilter); + } + + private void unregisterDisconnectBroadcastReceiver() { + getContext().unregisterReceiver(networkDisconnectBroadcastReceiver); + getContext().unregisterReceiver(usbDisconnectBroadcastReceiver); + } + + public class NetworkDisconnectBroadcastReceiver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + // Perform the Action that you need here on a Disconnect + isNetworkDrop = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getBoolean("isNetworkDrop", false); + + if(isNetworkDrop){ + Toast.makeText(getActivity(), "Network Dropped", Toast.LENGTH_LONG).show(); + } + } + } + + public class USBDisconnectBroadcastReceiver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + // Perform the Action that you need here on a Disconnect + isUSBDrop = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getBoolean("isUSBDrop", false); + + if(isUSBDrop){ + Toast.makeText(getActivity(), "USB Dropped", Toast.LENGTH_LONG).show(); + } + } + } @Override public void onResume() { super.onResume(); @@ -215,7 +276,7 @@ public void onResume() { mDisconnect.setVisibility(View.VISIBLE); mRestartTraceFile.setVisibility(View.GONE); } - + registerDisconnectBroadcastReceiver(); } @Override @@ -225,7 +286,7 @@ public synchronized void onPause() { getActivity().unbindService(mConnection); mVehicleManager = null; } - + unregisterDisconnectBroadcastReceiver(); } @Override diff --git a/enabler/src/main/java/com/openxc/enabler/VehicleDashboardFragment.java b/enabler/src/main/java/com/openxc/enabler/VehicleDashboardFragment.java index d57d37d6d..e2595c7f8 100644 --- a/enabler/src/main/java/com/openxc/enabler/VehicleDashboardFragment.java +++ b/enabler/src/main/java/com/openxc/enabler/VehicleDashboardFragment.java @@ -7,13 +7,17 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.v4.app.ListFragment; +import android.preference.PreferenceManager; +import androidx.fragment.app.ListFragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; +import com.openxc.remote.ViConnectionListener; import com.openxc.VehicleManager; +import com.openxc.interfaces.VehicleInterfaceDescriptor; import com.openxc.messages.EventedSimpleVehicleMessage; import com.openxc.messages.SimpleVehicleMessage; import com.openxc.messages.VehicleMessage; @@ -59,7 +63,27 @@ public void setUserVisibleHint(boolean isVisibleToUser) { } } } + private ViConnectionListener mConnectionListener = new ViConnectionListener.Stub() { + public void onConnected(final VehicleInterfaceDescriptor descriptor) { + Log.d(TAG, descriptor + " is now connected"); + } + public void onDisconnected() { + if (getActivity() != null) { + getActivity().runOnUiThread(new Runnable() { + public void run() { + Log.d(TAG, "VI disconnected"); + disconnectAlert(); + } + }); + } + } + }; + public void disconnectAlert() { + if (PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getBoolean("isPowerDrop", false)) { + Toast.makeText(getActivity(), "VI Power Droped", Toast.LENGTH_LONG).show(); + } + } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/BluetoothPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/BluetoothPreferenceManager.java index 652f447af..65d57d992 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/BluetoothPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/BluetoothPreferenceManager.java @@ -87,7 +87,7 @@ public void close() { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.vehicle_interface_key, R.string.bluetooth_polling_key, @@ -106,7 +106,9 @@ public void readStoredPreferences() { getPreferences().getBoolean( getString(R.string.bluetooth_polling_key), true)); } - }; + };*/ + + return new PreferenceListenerImpl(this); } private synchronized void setBluetoothStatus(boolean enabled) { @@ -174,4 +176,48 @@ private void persistCandidateDiscoveredDevices() { DeviceManager.KNOWN_BLUETOOTH_DEVICE_PREF_KEY, candidates); editor.commit(); } + + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.vehicle_interface_key, + R.string.bluetooth_polling_key, + R.string.bluetooth_mac_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final BluetoothPreferenceManager reference = (BluetoothPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setBluetoothStatus(reference.getPreferences().getString( + reference.getString(R.string.vehicle_interface_key), "").equals( + reference.getString(R.string.bluetooth_interface_option_value))); + reference.getVehicleManager().setBluetoothPollingStatus( + reference.getPreferences().getBoolean( + reference.getString(R.string.bluetooth_polling_key), true)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } + } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/DweetingPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/DweetingPreferenceManager.java index 3eb754d17..708cbb5c6 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/DweetingPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/DweetingPreferenceManager.java @@ -29,7 +29,7 @@ public void close() { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.dweeting_checkbox_key, R.string.dweeting_thingname_key @@ -43,7 +43,8 @@ public void readStoredPreferences() { setDweetingStatus(getPreferences().getBoolean(getString( R.string.dweeting_checkbox_key), false)); } - }; + };*/ + return new PreferenceListenerImpl(this); } private void setDweetingStatus(boolean enabled) { @@ -81,4 +82,43 @@ private void stopDweeting() { mDweeter = null; } } + + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.dweeting_checkbox_key, + R.string.dweeting_thingname_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final DweetingPreferenceManager reference + = (DweetingPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setDweetingStatus(reference.getPreferences().getBoolean( + reference.getString(R.string.dweeting_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/FileRecordingPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/FileRecordingPreferenceManager.java index 2c9c4c448..36067acbe 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/FileRecordingPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/FileRecordingPreferenceManager.java @@ -32,7 +32,7 @@ public void close() { protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.recording_checkbox_key, }; @@ -46,8 +46,8 @@ public void readStoredPreferences() { getString(R.string.recording_checkbox_key), false)); } - }; - + };*/ + return new PreferenceListenerImpl(this); } public void splitTraceFile(boolean enable) { @@ -112,11 +112,48 @@ public void startTraceRecording() { String directory = getPreferenceString(R.string.recording_directory_key); if (directory != null) { if (mFileRecorder != null) { - getVehicleManager().addSink(mFileRecorder); - //mFileRecorder = new FileRecorderSink(new AndroidFileOpener(directory)); - //getVehicleManager().addSink(mFileRecorder); + getVehicleManager().addSink(mFileRecorder); + //mFileRecorder = new FileRecorderSink(new AndroidFileOpener(directory)); + //getVehicleManager().addSink(mFileRecorder); + } } } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private static final int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.recording_checkbox_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final FileRecordingPreferenceManager reference + = (FileRecordingPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setFileRecordingStatus(reference.getPreferences().getBoolean( + reference.getString(R.string.recording_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/GpsOverwritePreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/GpsOverwritePreferenceManager.java index f2451b370..e307fca08 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/GpsOverwritePreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/GpsOverwritePreferenceManager.java @@ -29,7 +29,7 @@ public void close() { } protected PreferenceListener createPreferenceListener(){ - return new PreferenceListener() { + /*return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.gps_overwrite_checkbox_key, }; @@ -42,7 +42,8 @@ public void readStoredPreferences() { setNativeGpsOverwriteStatus(getPreferences().getBoolean( getString(R.string.gps_overwrite_checkbox_key), false)); } - }; + };*/ + return new PreferenceListenerImpl(this); } private void setNativeGpsOverwriteStatus(boolean enabled) { @@ -53,4 +54,41 @@ private void setNativeGpsOverwriteStatus(boolean enabled) { } mVehicleLocationProvider.setOverwritingStatus(enabled); } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.gps_overwrite_checkbox_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final GpsOverwritePreferenceManager reference + = (GpsOverwritePreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setNativeGpsOverwriteStatus(reference.getPreferences().getBoolean( + reference.getString(R.string.gps_overwrite_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/NativeGpsPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/NativeGpsPreferenceManager.java index db001047f..18233b5e3 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/NativeGpsPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/NativeGpsPreferenceManager.java @@ -1,13 +1,14 @@ package com.openxc.enabler.preferences; import android.content.Context; - +import android.util.Log; import com.openxcplatform.enabler.R; /** * Enable or disable reading GPS from the native Android stack. */ public class NativeGpsPreferenceManager extends VehiclePreferenceManager { + private final static String TAG = "VehiclePreferenceManager"; public NativeGpsPreferenceManager(Context context) { super(context); } @@ -18,8 +19,48 @@ public void close() { getVehicleManager().setNativeGpsStatus(false); } } - protected PreferenceListener createPreferenceListener() { + return new PreferenceListenerImpl(this); + } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.native_gps_checkbox_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final NativeGpsPreferenceManager reference + = (NativeGpsPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.getVehicleManager().setNativeGpsStatus(reference.getPreferences().getBoolean( + reference.getString(R.string.native_gps_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } + + /* protected PreferenceListener createPreferenceListener() { return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.native_gps_checkbox_key, @@ -34,5 +75,5 @@ public void readStoredPreferences() { getString(R.string.native_gps_checkbox_key), false)); } }; - } + }*/ } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/NetworkPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/NetworkPreferenceManager.java index 0ed78ccee..d08a26afb 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/NetworkPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/NetworkPreferenceManager.java @@ -19,7 +19,7 @@ public NetworkPreferenceManager(Context context) { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.vehicle_interface_key, R.string.network_host_key, @@ -35,7 +35,8 @@ public void readStoredPreferences() { getString(R.string.vehicle_interface_key), "").equals( getString(R.string.network_interface_option_value))); } - }; + };*/ + return new PreferenceListenerImpl(this); } private void setNetworkStatus(boolean enabled) { @@ -65,4 +66,43 @@ private void setNetworkStatus(boolean enabled) { } } } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.vehicle_interface_key, + R.string.network_host_key, + R.string.network_port_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final NetworkPreferenceManager reference = (NetworkPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setNetworkStatus(reference.getPreferences().getString( + reference.getString(R.string.vehicle_interface_key), "").equals( + reference.getString(R.string.network_interface_option_value))); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/PhoneSensorSourcePreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/PhoneSensorSourcePreferenceManager.java index 2b06f10b5..cb7fef39c 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/PhoneSensorSourcePreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/PhoneSensorSourcePreferenceManager.java @@ -27,7 +27,7 @@ public void close() { @Override protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.phone_source_polling_checkbox_key }; @@ -39,10 +39,11 @@ protected int[] getWatchedPreferenceKeyIds() { public void readStoredPreferences() { setPhoneSensorSourceStatus(getPreferences().getBoolean(getString(R.string.phone_source_polling_checkbox_key),false)); } - }; + };*/ + return new PreferenceListenerImpl(this); } - private synchronized void setPhoneSensorSourceStatus(boolean enabled) { + private void setPhoneSensorSourceStatus(boolean enabled) { Log.i(TAG, "Setting phone source setting to " + enabled); if(enabled) { if(mPhoneSensorSource == null) { @@ -71,4 +72,43 @@ private synchronized void stopSensorCapture() { mPhoneSensorSource = null; } } + + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.phone_source_polling_checkbox_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final PhoneSensorSourcePreferenceManager reference + = (PhoneSensorSourcePreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setPhoneSensorSourceStatus(reference.getPreferences().getBoolean( + reference.getString(R.string.phone_source_polling_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } + } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/TraceSourcePreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/TraceSourcePreferenceManager.java index 29cd4426d..cf815695f 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/TraceSourcePreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/TraceSourcePreferenceManager.java @@ -27,7 +27,7 @@ public void close() { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.vehicle_interface_key, R.string.trace_source_file_key, @@ -42,7 +42,8 @@ public void readStoredPreferences() { getString(R.string.vehicle_interface_key), "").equals( getString(R.string.trace_interface_option_value))); } - }; + };*/ + return new PreferenceListenerImpl(this); } private synchronized void setTraceSourceStatus(boolean enabled) { @@ -89,4 +90,43 @@ private synchronized void stopTrace() { mTraceSource = null; } } + + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.vehicle_interface_key, + R.string.trace_source_file_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final TraceSourcePreferenceManager reference = (TraceSourcePreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setTraceSourceStatus(reference.getPreferences().getString( + reference.getString(R.string.vehicle_interface_key), "").equals( + reference.getString(R.string.trace_interface_option_value))); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/UploadingPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/UploadingPreferenceManager.java index 29562e25b..267233faa 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/UploadingPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/UploadingPreferenceManager.java @@ -29,7 +29,7 @@ public void close() { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /* return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.uploading_checkbox_key, R.string.uploading_path_key, @@ -43,7 +43,8 @@ public void readStoredPreferences() { setUploadingStatus(getPreferences().getBoolean(getString( R.string.uploading_checkbox_key), false)); } - }; + };*/ + return new PreferenceListenerImpl(this); } private void setUploadingStatus(boolean enabled) { @@ -82,4 +83,41 @@ private void stopUploading() { mUploader = null; } } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.uploading_checkbox_key, + R.string.uploading_path_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final UploadingPreferenceManager reference = (UploadingPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setUploadingStatus(reference.getPreferences().getBoolean(reference.getString( + R.string.uploading_checkbox_key), false)); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/UsbPreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/UsbPreferenceManager.java index e65d35569..0d2369618 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/UsbPreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/UsbPreferenceManager.java @@ -18,7 +18,7 @@ public UsbPreferenceManager(Context context) { } protected PreferenceListener createPreferenceListener() { - return new PreferenceListener() { + /*return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.vehicle_interface_key }; @@ -32,7 +32,8 @@ public void readStoredPreferences() { getString(R.string.vehicle_interface_key), "").equals( getString(R.string.usb_interface_option_value))); } - }; + };*/ + return new PreferenceListenerImpl(this); } private synchronized void setUsbStatus(boolean enabled) { @@ -46,4 +47,41 @@ private synchronized void setUsbStatus(boolean enabled) { } } } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.vehicle_interface_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final UsbPreferenceManager reference = (UsbPreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + reference.setUsbStatus(reference.getPreferences().getString( + reference.getString(R.string.vehicle_interface_key), "").equals( + reference.getString(R.string.usb_interface_option_value))); + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/VehicleInterfacePreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/VehicleInterfacePreferenceManager.java index d2983939e..20737d729 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/VehicleInterfacePreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/VehicleInterfacePreferenceManager.java @@ -1,16 +1,65 @@ package com.openxc.enabler.preferences; import android.content.Context; - +import android.util.Log; import com.openxc.remote.VehicleServiceException; import com.openxcplatform.enabler.R; public class VehicleInterfacePreferenceManager extends VehiclePreferenceManager { + private final static String TAG = "VehicleInterfacePreferenceManager"; public VehicleInterfacePreferenceManager(Context context) { super(context); } protected PreferenceListener createPreferenceListener() { + return new PreferenceListenerImpl(this); + } + /** + * Internal implementation of the {@link VehiclePreferenceManager.PreferenceListener} + * interface. + */ + private static final class PreferenceListenerImpl extends PreferenceListener { + + private final static int[] WATCHED_PREFERENCE_KEY_IDS = { + R.string.vehicle_interface_key + }; + + /** + * Main constructor. + * + * @param reference Reference to the enclosing class. + */ + private PreferenceListenerImpl(final VehiclePreferenceManager reference) { + super(reference); + } + + @Override + protected void readStoredPreferences() { + final VehicleInterfacePreferenceManager reference + = (VehicleInterfacePreferenceManager) getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not read stored preferences, enclosing instance is null"); + return; + } + + String selectedVi = reference.getPreferences().getString( + reference.getString(R.string.vehicle_interface_key), ""); + if(selectedVi.equals(reference.getString( + R.string.disabled_interface_option_value))) { + try { + reference.getVehicleManager().setVehicleInterface(null); + } catch(VehicleServiceException e) { + } + } + } + + @Override + protected int[] getWatchedPreferenceKeyIds() { + return WATCHED_PREFERENCE_KEY_IDS; + } + } + + /*protected PreferenceListener createPreferenceListener() { return new PreferenceListener() { private int[] WATCHED_PREFERENCE_KEY_IDS = { R.string.vehicle_interface_key @@ -32,5 +81,5 @@ public void readStoredPreferences() { } } }; - } + }*/ } diff --git a/enabler/src/main/java/com/openxc/enabler/preferences/VehiclePreferenceManager.java b/enabler/src/main/java/com/openxc/enabler/preferences/VehiclePreferenceManager.java index 32506b22d..be178bdec 100644 --- a/enabler/src/main/java/com/openxc/enabler/preferences/VehiclePreferenceManager.java +++ b/enabler/src/main/java/com/openxc/enabler/preferences/VehiclePreferenceManager.java @@ -3,8 +3,9 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; - +import android.util.Log; import com.openxc.VehicleManager; +import java.lang.ref.WeakReference; /** * Abstract base class that collects functionality common to watching shared @@ -14,6 +15,7 @@ * contained in a subclass, instead of all cluttering up the main activity. */ public abstract class VehiclePreferenceManager { + private final static String TAG = "VehiclePreferenceManager"; private Context mContext; private PreferenceListener mPreferenceListener; private SharedPreferences mPreferences; @@ -66,7 +68,7 @@ protected VehicleManager getVehicleManager() { */ protected abstract PreferenceListener createPreferenceListener(); - protected abstract class PreferenceListener implements + protected static abstract class PreferenceListener implements SharedPreferences.OnSharedPreferenceChangeListener { /** @@ -82,12 +84,53 @@ protected abstract class PreferenceListener implements * preference keys that should be monitored for changes. */ protected abstract int[] getWatchedPreferenceKeyIds(); + /** + * Reference to enclosing class. + */ + private final WeakReference mReference; + + /** + * Default constructor. + * + * @param reference Reference to enclosing class. + */ + protected PreferenceListener(final VehiclePreferenceManager reference) { + super(); + mReference = new WeakReference<>(reference); + } + + /** + * Returns a reference to the enclosing class. + * + * @return A reference to the enclosing class or {@code null} if a reference is + * garbage collected. + */ + protected VehiclePreferenceManager getEnclosingReference() { + return mReference.get(); + } + /** * If any of the watched preference keys changed, trigger a refresh of * the service. */ public void onSharedPreferenceChanged(SharedPreferences preferences, + String key) { + final VehiclePreferenceManager reference = getEnclosingReference(); + if (reference == null) { + Log.w(TAG, "Can not handle shared preferenced changes, enclosing reference is null"); + return; + } + + for(int watchedKeyId : getWatchedPreferenceKeyIds()) { + if(key.equals(reference.getString(watchedKeyId))) { + readStoredPreferences(); + break; + } + } + } + } + /* public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { for(int watchedKeyId : getWatchedPreferenceKeyIds()) { if(key.equals(getString(watchedKeyId))) { @@ -96,7 +139,7 @@ public void onSharedPreferenceChanged(SharedPreferences preferences, } } } - } + }*/ private void unwatchPreferences(SharedPreferences preferences, PreferenceListener listener) { diff --git a/enabler/src/main/res/layout/main.xml b/enabler/src/main/res/layout/main.xml index 0586da174..02f60daaf 100644 --- a/enabler/src/main/res/layout/main.xml +++ b/enabler/src/main/res/layout/main.xml @@ -4,13 +4,13 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - + Recording Data Sources About + Notification GPS + NOTIFICATION Output Bluetooth Record Trace @@ -32,6 +34,9 @@ API Source Name Retrieve your uploaded data using this source name in the API Use built-in GPS + Power Drop + Network Drop + USB Drop For vehicles without a GPS receiver, send the host\'s built-in GPS location instead Overwrite Native GPS Overwrite Android native GPS values with those from the vehicle (if available) @@ -50,6 +55,7 @@ Include Data from Phone Sensors Disable Trace Playing In Loop About OpenXC + NOTIFICATION OpenXC Version Version Number application_version diff --git a/enabler/src/main/res/xml/notification_preferences.xml b/enabler/src/main/res/xml/notification_preferences.xml new file mode 100644 index 000000000..39eba8d0c --- /dev/null +++ b/enabler/src/main/res/xml/notification_preferences.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/enabler/src/main/res/xml/preference_headers.xml b/enabler/src/main/res/xml/preference_headers.xml index a1e6bb8a7..7315f01c2 100644 --- a/enabler/src/main/res/xml/preference_headers.xml +++ b/enabler/src/main/res/xml/preference_headers.xml @@ -7,6 +7,8 @@ android:title="@string/recording_preferences" />
+
diff --git a/enabler/src/main/res/xml/preference_headers_legacy.xml b/enabler/src/main/res/xml/preference_headers_legacy.xml index 8eef34120..42bdc51f2 100644 --- a/enabler/src/main/res/xml/preference_headers_legacy.xml +++ b/enabler/src/main/res/xml/preference_headers_legacy.xml @@ -20,6 +20,13 @@ android:targetClass="com.openxc.enabler.SettingsActivity" android:action="com.openxc.enabler.preferences.OUTPUT" /> + + + + + + + diff --git a/fabfile.py b/fabfile.py index f7478667d..bb3f1973c 100644 --- a/fabfile.py +++ b/fabfile.py @@ -5,7 +5,7 @@ from fabric.colors import green, yellow from fabric.contrib.console import confirm -from prettyprint import pp +import pprint import re VERSION_PATTERN = r'^v\d+(\.\d+)+?$' @@ -16,7 +16,12 @@ proxy = os.environ.get('http_proxy', None) env.http_proxy = env.http_proxy_port = None if proxy is not None: - env.http_proxy, env.http_proxy_port = proxy.rsplit(":") + proxys = proxy.rsplit(":") + if len(proxys) > 2: + env.http_proxy = proxys[0] + ':' + proxys[1] + env.http_proxy_port = proxys[2] + else: + env.http_proxy, env.http_proxy_port = proxys def latest_git_tag(): @@ -62,6 +67,7 @@ def make_tag(): if confirm(yellow("Tag this release?"), default=True): print(green("The last 5 tags were: ")) tags = local('git tag | tail -n 20', capture=True) + pp = pprint.PrettyPrinter() pp(sorted(tags.split('\n'), compare_versions, reverse=True)) prompt("New release tag in the format vX.Y[.Z]?", 'tag', validate=VERSION_PATTERN) diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..5465fec0e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +android.enableJetifier=true +android.useAndroidX=true \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index c92781091..002489422 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -27,7 +27,7 @@ dependencies { api 'com.google.guava:guava:24.1-android' implementation 'com.google.protobuf:protobuf-java:3.9.2' implementation 'commons-io:commons-io:2.6' - implementation 'com.android.support:support-v4:28.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0-beta01' testImplementation 'junit:junit:4.12' testImplementation 'org.hamcrest:hamcrest-all:1.3' diff --git a/library/src/main/java/com/openxc/interfaces/network/NetworkVehicleInterface.java b/library/src/main/java/com/openxc/interfaces/network/NetworkVehicleInterface.java index f20843fbb..0faec6b98 100644 --- a/library/src/main/java/com/openxc/interfaces/network/NetworkVehicleInterface.java +++ b/library/src/main/java/com/openxc/interfaces/network/NetworkVehicleInterface.java @@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit; import android.content.Context; +import android.content.Intent; import android.util.Log; import com.google.common.base.MoreObjects; @@ -27,6 +28,7 @@ */ public class NetworkVehicleInterface extends BytestreamDataSource implements VehicleInterface { + public static final String BROADCAST_NETWORK_DISCONNECTED = "com.openxc.interfaces.network.NetworkVehicleInterface.disconnected"; private static final String TAG = "NetworkVehicleInterface"; private static final int SOCKET_TIMEOUT = 10000; private static final String SCHEMA_SPECIFIC_PREFIX = "//"; @@ -210,6 +212,7 @@ protected void disconnect() { mConnectionLock.writeLock().unlock(); } Log.d(TAG, "Disconnected from the socket"); + sendNetworkDisconnectBroadcast(); } /** @@ -282,4 +285,12 @@ private void setUri(URI uri) throws DataSourceResourceException { mUri = uri; } + + // For an example on BroadcastReceivers and Broadcast Intents see + // https://www.techotopia.com/index.php/Android_Broadcast_Intents_and_Broadcast_Receivers + protected void sendNetworkDisconnectBroadcast() { + Intent intent = new Intent(); + intent.setAction(BROADCAST_NETWORK_DISCONNECTED); + getContext().sendBroadcast(intent); + } } diff --git a/library/src/main/java/com/openxc/interfaces/usb/UsbVehicleInterface.java b/library/src/main/java/com/openxc/interfaces/usb/UsbVehicleInterface.java index 292d5052e..263a504a5 100644 --- a/library/src/main/java/com/openxc/interfaces/usb/UsbVehicleInterface.java +++ b/library/src/main/java/com/openxc/interfaces/usb/UsbVehicleInterface.java @@ -43,6 +43,7 @@ @TargetApi(12) public class UsbVehicleInterface extends BytestreamDataSource implements VehicleInterface { + public static final String BROADCAST_USB_DISCONNECTED = "com.openxc.interfaces.network.NetworkVehicleInterface.disconnected"; private static final String TAG = "UsbVehicleInterface"; private static final int ENDPOINT_COUNT = 2; @@ -339,7 +340,7 @@ private void openConnection(UsbDevice device) { Log.i(TAG, "Connected to USB device with " + mConnection); } catch(UsbDeviceException e) { - Log.w("Couldn't open USB device", e); + Log.w("not open USB device", e); } finally { mConnectionLock.writeLock().unlock(); } @@ -372,6 +373,7 @@ protected void disconnect() { } finally { mConnectionLock.writeLock().unlock(); } + sendUSBDisconnectBroadcast(); } private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @@ -439,4 +441,9 @@ private static URI createUri(URI uri) throws DataSourceResourceException { private static boolean validateResource(URI uri) { return uri.getScheme() != null && uri.getScheme().equals("usb"); } + protected void sendUSBDisconnectBroadcast() { + Intent intent = new Intent(); + intent.setAction(BROADCAST_USB_DISCONNECTED); + getContext().sendBroadcast(intent); + } } diff --git a/library/src/main/java/com/openxc/remote/VehicleService.java b/library/src/main/java/com/openxc/remote/VehicleService.java index af04403e1..1bdf8c03a 100644 --- a/library/src/main/java/com/openxc/remote/VehicleService.java +++ b/library/src/main/java/com/openxc/remote/VehicleService.java @@ -9,7 +9,7 @@ import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; -import android.support.v4.app.NotificationCompat; +import androidx.core.app.NotificationCompat; import android.util.Log; import com.openxc.DataPipeline; diff --git a/library/src/main/java/com/openxc/sources/PhoneSensorSource.java b/library/src/main/java/com/openxc/sources/PhoneSensorSource.java index 00a54f042..5311ff0de 100644 --- a/library/src/main/java/com/openxc/sources/PhoneSensorSource.java +++ b/library/src/main/java/com/openxc/sources/PhoneSensorSource.java @@ -14,7 +14,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Looper; -import android.support.v4.app.ActivityCompat; +import androidx.core.app.ActivityCompat; import android.util.Log; import com.google.common.base.MoreObjects; diff --git a/library/src/main/java/com/openxc/sources/trace/TraceVehicleDataSource.java b/library/src/main/java/com/openxc/sources/trace/TraceVehicleDataSource.java index e21561318..0752e9f14 100644 --- a/library/src/main/java/com/openxc/sources/trace/TraceVehicleDataSource.java +++ b/library/src/main/java/com/openxc/sources/trace/TraceVehicleDataSource.java @@ -2,11 +2,10 @@ import android.Manifest; import android.content.Context; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.preference.PreferenceManager; -import android.support.v4.content.ContextCompat; +import androidx.core.content.ContextCompat; import android.util.Log; import com.google.common.base.MoreObjects; diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml index d89869d73..6ad654940 100644 --- a/library/src/main/res/values/strings.xml +++ b/library/src/main/res/values/strings.xml @@ -4,6 +4,9 @@ Connected to vehicle use_native_gps + power_drop + network_drop + usb_drop overwrite_native_gps recording_enabled recording_output diff --git a/scripts/push-javadoc.sh b/scripts/push-javadoc.sh new file mode 100755 index 000000000..4d3c144d8 --- /dev/null +++ b/scripts/push-javadoc.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +if [ "$TRAVIS_REPO_SLUG" == "openxc/openxc-android" ] && [ "$TRAVIS_JDK_VERSION" == "openjdk8" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then + + cp -R library/build/docs/javadoc $HOME/javadoc-latest + + cd $HOME + git config --global user.email "travis@travis-ci.org" + git config --global user.name "Travis-CI" + + git clone --quiet --branch=master https://${GH_TOKEN}@github.com/openxc/openxc-android master > /dev/null + cd master + LATEST_TAG=$(git describe --abbrev=0 --tags) + cd ../ + + git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/openxc/openxc-android gh-pages > /dev/null + cd gh-pages + + git rm -rf ./ + echo "android.openxcplatform.com" > CNAME + cp -Rf $HOME/javadoc-latest/. ./ + git add -f . + git commit -m "JavaDoc $LATEST_TAG - Travis Build $TRAVIS_BUILD_NUMBER" + git push -fq origin gh-pages > /dev/null + +fi \ No newline at end of file diff --git a/scripts/updatedocs.sh b/scripts/updatedocs.sh deleted file mode 100755 index 7154c1bfb..000000000 --- a/scripts/updatedocs.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -set -ex - -CURRENT_BRANCH=`git symbolic-ref HEAD 2>/dev/null | awk -F/ {'print $NF'}` -TEMP_PATH=/tmp/openxc-apidocs -rm -rf $TEMP_PATH -cp -R library/build/docs/javadoc/ $TEMP_PATH -git checkout gh-pages -git pull -rm -rf *.html references assets reference resources -cp -R $TEMP_PATH/* . -git add -A -git commit -m "Update Javadocs." -git push -git checkout $CURRENT_BRANCH