summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Grover <joeygrover@gmail.com>2018-06-08 10:24:14 -0400
committerGitHub <noreply@github.com>2018-06-08 10:24:14 -0400
commit02fc4bbbc7dd2f180da95eca8e766e11e312bd54 (patch)
tree44778ccc0cb6ce2077762f28c4031078f8ac37cc
parentffec7f5289672d39f2a230bedd2584bc7c73013d (diff)
parent432a06a16f4a9390e32af668d8ffc9dcb726c006 (diff)
downloadsdl_android-02fc4bbbc7dd2f180da95eca8e766e11e312bd54.tar.gz
Merge pull request #779 from smartdevicelink/feature/less_notification
Less intrusive Router Service Notification
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java13
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java24
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java89
3 files changed, 102 insertions, 24 deletions
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java b/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
index cf5ace221..6e752217b 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
@@ -55,6 +55,7 @@ public class MultiplexBluetoothTransport {
private static final String NAME_SECURE =" SdlRouterService";
// Key names received from the BluetoothSerialServer Handler
public static final String DEVICE_NAME = "device_name";
+ public static final String DEVICE_ADDRESS = "device_address";
public static final String TOAST = "toast";
private static final long MS_TILL_TIMEOUT = 2500;
private static final int READ_BUFFER_SIZE = 4096;
@@ -259,15 +260,17 @@ public class MultiplexBluetoothTransport {
mConnectedWriteThread = new ConnectedWriteThread(socket);
mConnectedWriteThread.start();
- //Store a static name of the device that is connected.
- if(device!=null){
- currentlyConnectedDevice = device.getName();
- }
+
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(SdlRouterService.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
- bundle.putString(DEVICE_NAME, currentlyConnectedDevice);
+ //Store a static name of the device that is connected.
+ currentlyConnectedDevice = device.getName();
+ if(currentlyConnectedDevice != null){
+ bundle.putString(DEVICE_NAME, currentlyConnectedDevice);
+ bundle.putString(DEVICE_ADDRESS, device.getAddress());
+ }
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
index ea406250a..dc40f43bf 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
@@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -58,8 +59,9 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//Log.i(TAG, "Sdl Receiver Activated");
- String action = intent.getAction();
-
+ final String action = intent.getAction();
+ BluetoothDevice device = null;
+
if(action.equalsIgnoreCase(Intent.ACTION_PACKAGE_ADDED)
|| action.equalsIgnoreCase(Intent.ACTION_PACKAGE_REPLACED)){
//The package manager has sent out a new broadcast.
@@ -83,7 +85,11 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
onSdlEnabled(context, intent);
return;
}
-
+
+ if(intent.hasExtra(BluetoothDevice.EXTRA_DEVICE)){ //Grab the bluetooth device if available
+ device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ }
+
boolean didStart = false;
if (localRouterClass == null){
localRouterClass = defineLocalSdlRouterClass();
@@ -133,13 +139,13 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
}else if(intent.getBooleanExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA, false)){
//We were told to wake up our router services
boolean altServiceWake = intent.getBooleanExtra(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT, false);
- didStart = wakeUpRouterService(context, false,altServiceWake );
+ didStart = wakeUpRouterService(context, false,altServiceWake,device );
}
}
- if (intent.getAction().contains("android.bluetooth.adapter.action.STATE_CHANGED")){
+ if (action.contains("android.bluetooth.adapter.action.STATE_CHANGED")){
int state = intent.getIntExtra("android.bluetooth.adapter.extra.STATE",-1);
if (state == BluetoothAdapter.STATE_OFF ||
state == BluetoothAdapter.STATE_TURNING_OFF){
@@ -150,11 +156,12 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
return;
}
}
+
Log.d(TAG, "Check for local router");
if(localRouterClass!=null){ //If there is a supplied router service lets run some logic regarding starting one
if(!didStart){Log.d(TAG, "attempting to wake up router service");
- didStart = wakeUpRouterService(context, true,false);
+ didStart = wakeUpRouterService(context, true,false, device);
}
//So even though we started our own version, on some older phones we find that two services are started up so we want to make sure we send our version that we are working with
@@ -169,7 +176,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
}
}
- private boolean wakeUpRouterService(final Context context, final boolean ping, final boolean altTransportWake){
+ private boolean wakeUpRouterService(final Context context, final boolean ping, final boolean altTransportWake, final BluetoothDevice device){
new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() {
@Override
public void onComplete(Vector<ComponentName> routerServices) {
@@ -191,6 +198,9 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
if (altTransportWake) {
serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
}
+ if(device != null){
+ serviceIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ }
try {
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
context.startService(serviceIntent);
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
index e136f0e78..1d0e29f77 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
@@ -6,7 +6,6 @@ import static com.smartdevicelink.transport.TransportConstants.HARDWARE_DISCONNE
import static com.smartdevicelink.transport.TransportConstants.SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME;
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -35,12 +34,12 @@ import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -127,7 +126,12 @@ public class SdlRouterService extends Service{
@SuppressWarnings("FieldCanBeLocal")
private final int UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530;
-
+
+ /**
+ * Preference location where the service stores known SDL status based on device address
+ */
+ protected static final String SDL_DEVICE_STATUS_SHARED_PREFS = "sdl.device.status";
+
private MultiplexBluetoothTransport mSerialService = null;
private static boolean connectAsClient = false;
@@ -896,15 +900,14 @@ public class SdlRouterService extends Service{
}
if(intent != null ){
if(intent.getBooleanExtra(FOREGROUND_EXTRA, false)){
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- int timeout = FOREGROUND_TIMEOUT;
- int state = adapter.getProfileConnectionState(BluetoothProfile.A2DP);
- if(state == BluetoothAdapter.STATE_CONNECTED){
- //If we've just connected over A2DP there is a fair chance we want to wait to
- // listen for a connection so we double our wait time
- timeout *= 2;
+ String address = null;
+ if(intent.hasExtra(BluetoothDevice.EXTRA_DEVICE)){
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if(device != null){
+ address = device.getAddress();
+ }
}
+ int timeout = getNotificationTimeout(address);
enterForeground("Waiting for connection...", timeout);
resetForegroundTimeOut(timeout);
}
@@ -998,6 +1001,31 @@ public class SdlRouterService extends Service{
}
}
+ /**
+ * Gets the correct timeout for the foreground notification.
+ * @param address the address of the device that is currently connected
+ * @return the amount of time for a timeout handler to remove the notification.
+ */
+ @SuppressLint("MissingPermission")
+ private int getNotificationTimeout(String address){
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if(address != null){
+ if(hasSDLConnected(address)){
+ return FOREGROUND_TIMEOUT * 2;
+ }else if(this.isFirstStatusCheck(address)){
+ // If this is the first time the service has ever connected to this device we want
+ // to give it a few extra seconds.
+ setSDLConnectedStatus(address,false);
+ return FOREGROUND_TIMEOUT;
+ }else{
+ // If the service has seen this device before but hasn't ever connected, the
+ // notification can be removed ASAP.
+ return FOREGROUND_TIMEOUT/100;
+ }
+ }
+ return FOREGROUND_TIMEOUT/100;
+ }
+
public void resetForegroundTimeOut(long delay){
if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2){
return;
@@ -1330,7 +1358,11 @@ public class SdlRouterService extends Service{
SdlRouterService service = this.provider.get();
switch (msg.what) {
case MESSAGE_DEVICE_NAME:
- service.connectedDeviceName = msg.getData().getString(MultiplexBluetoothTransport.DEVICE_NAME);
+ Bundle bundle = msg.getData();
+ if(bundle !=null) {
+ service.connectedDeviceName = bundle.getString(MultiplexBluetoothTransport.DEVICE_NAME);
+ service.setSDLConnectedStatus(bundle.getString(MultiplexBluetoothTransport.DEVICE_ADDRESS),true);
+ }
break;
case MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
@@ -1726,6 +1758,39 @@ public class SdlRouterService extends Service{
{
return 0;
}
+
+ /**
+ * Set the connection establishment status of the particular device
+ * @param address address of the device in quesiton
+ * @param hasSDLConnected true if a connection has been established, false if not
+ */
+ protected void setSDLConnectedStatus(String address, boolean hasSDLConnected){
+ SharedPreferences preferences = this.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putBoolean(address,hasSDLConnected);
+ editor.commit();
+ }
+
+ /**
+ * Checks to see if a device address has connected to SDL before.
+ * @param address the mac address of the device in quesiton
+ * @return if this is the first status check of this device
+ */
+ protected boolean isFirstStatusCheck(String address){
+ SharedPreferences preferences = this.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ return !preferences.contains(address) ;
+ }
+ /**
+ * Checks to see if a device address has connected to SDL before.
+ * @param address the mac address of the device in quesiton
+ * @return if an SDL connection has ever been established with this device
+ */
+ protected boolean hasSDLConnected(String address){
+ SharedPreferences preferences = this.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ return preferences.contains(address) && preferences.getBoolean(address,false);
+ }
+
+
/* ***********************************************************************************************************************************************************************
* ***************************************************************** CUSTOM ADDITIONS ************************************************************************************