diff options
author | Joey Grover <joeygrover@gmail.com> | 2018-10-05 13:54:03 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-05 13:54:03 -0400 |
commit | cc32c0296555df6c14536bcef531839588b4a99c (patch) | |
tree | ec0e70329b44e69667f38a1c78b2c36f91a9947c | |
parent | 7cf673a66fa128bdbc4452790aaa81a8f140703a (diff) | |
parent | f184f5c27c918112262aae372fd6c85757a0bca4 (diff) | |
download | sdl_android-cc32c0296555df6c14536bcef531839588b4a99c.tar.gz |
Merge pull request #891 from smartdevicelink/bugfix/legacy_usb
Fix issue with legacy USB connections
9 files changed, 153 insertions, 18 deletions
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java index b376d7276..e0674724f 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java +++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java @@ -90,6 +90,7 @@ import com.smartdevicelink.trace.enums.InterfaceActivityDirection; import com.smartdevicelink.transport.BaseTransportConfig;
import com.smartdevicelink.transport.MultiplexTransportConfig;
import com.smartdevicelink.transport.SiphonServer;
+import com.smartdevicelink.transport.USBTransportConfig;
import com.smartdevicelink.transport.enums.TransportType;
import com.smartdevicelink.util.CorrelationIdGenerator;
import com.smartdevicelink.util.DebugTool;
@@ -111,6 +112,8 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
@@ -1471,6 +1474,24 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> _systemCapabilityManager = new SystemCapabilityManager(_internalInterface);
// Setup SdlConnection
synchronized(CONNECTION_REFERENCE_LOCK) {
+
+ //Handle legacy USB connections
+ if(_transportConfig != null
+ && TransportType.USB.equals(_transportConfig.getTransportType())){
+ //A USB transport config was provided
+ USBTransportConfig usbTransportConfig = (USBTransportConfig)_transportConfig;
+ if(usbTransportConfig.getUsbAccessory() == null){
+ DebugTool.logInfo("Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service");
+ //The accessory was null which means it came from a router service
+ MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(),_appID);
+ multiplexTransportConfig.setRequiresHighBandwidth(true);
+ multiplexTransportConfig.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF);
+ multiplexTransportConfig.setPrimaryTransports(Collections.singletonList(TransportType.USB));
+ multiplexTransportConfig.setSecondaryTransports(new ArrayList<TransportType>());
+ _transportConfig = multiplexTransportConfig;
+ }
+ }
+
if(_transportConfig.getTransportType().equals(TransportType.MULTIPLEX)){
this.sdlSession = new SdlSession2(_interfaceBroker,(MultiplexTransportConfig)_transportConfig);
}else{
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransportConfig.java b/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransportConfig.java index ec4e877da..8a3e39d20 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransportConfig.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransportConfig.java @@ -157,6 +157,13 @@ public class MultiplexTransportConfig extends BaseTransportConfig{ * Set whether or not this app requires the use of a transport that supports high bandwidth * services. Common use is when an app uses the video/audio streaming services and there is no * other integration that could be useful to the user. + * <br><br> <b>For example:</b> + * <br><b>1. </b>If an app intends to perform audio or video streaming and does not wish + * to appear on the module when that isn't possible, a value of true should be sent. + * <br><b>2. </b>If the same app wishes to appear on the module even when those services aren't available + * a value of true should be sent. In this case, the app could display a message prompting the + * user to "Please connect USB or Wifi" or it could have a separate integration like giving turn + * by turn directions in place of streaming the full navigation map. * @param requiresHighBandwidth whether the app should be treated as requiring a high * bandwidth transport. */ @@ -242,13 +249,13 @@ public class MultiplexTransportConfig extends BaseTransportConfig{ * @param connectedTransports the currently connected transports * @param audioStreamTransportAvail true if there is either an audio streaming supported * transport currently connected or a transport is - * available to connect with. false if there is no + * available to connect with. False if there is no * transport connected to support audio streaming and * no possibility in the foreseeable future. - * @param videoStreamTransportAvail true if there is either an audio streaming supported + * @param videoStreamTransportAvail true if there is either a video streaming supported * transport currently connected or a transport is - * available to connect with. false if there is no - * transport connected to support audio streaming and + * available to connect with. False if there is no + * transport connected to support video streaming and * no possibility in the foreseeable future. */ void onTransportEvent(List<TransportRecord> connectedTransports, boolean audioStreamTransportAvail,boolean videoStreamTransportAvail); diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java b/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java index d4b341721..868c71054 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java @@ -23,6 +23,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Build; +import android.support.annotation.NonNull; import android.util.Log; import com.smartdevicelink.util.AndroidTools; @@ -99,6 +100,14 @@ public class RouterServiceValidator { inDebugMode = inDebugMode(); this.service = service; } + + public RouterServiceValidator(@NonNull MultiplexTransportConfig config){ + this.context = config.context; + this.service = config.service; + setSecurityLevel(config.securityLevel); + inDebugMode = inDebugMode(); + } + /** * Main function to call to ensure we are connecting to a validated router service * @return whether or not the currently running router service can be trusted. 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 d76194db6..b96ac4f65 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java @@ -44,11 +44,14 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.hardware.usb.UsbManager; import android.os.Build; +import android.os.Parcelable; import android.util.Log; import com.smartdevicelink.R; import com.smartdevicelink.transport.RouterServiceValidator.TrustedListCallback; +import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.util.AndroidTools; import com.smartdevicelink.util.SdlAppInfo; import com.smartdevicelink.util.ServiceFinder; @@ -164,6 +167,12 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ //List obtained. Let's start our service queuedService = componentName; finalIntent.setAction("com.sdl.noaction"); //Replace what's there so we do go into some unintended loop + String transportType = finalIntent.getStringExtra(TransportConstants.START_ROUTER_SERVICE_TRANSPORT_CONNECTED); + if(transportType!= null ){ + if(TransportType.USB.toString().equals(transportType)){ + finalIntent.putExtra(UsbManager.EXTRA_ACCESSORY, (Parcelable)null); + } + } onSdlEnabled(finalContext, finalIntent); } 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 b566b0a82..4b37dfd24 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java @@ -1593,6 +1593,11 @@ public class SdlRouterService extends Service{ startService.putExtra(TransportConstants.FORCE_TRANSPORT_CONNECTED, true); startService.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE, getBaseContext().getPackageName()); startService.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME, new ComponentName(this, this.getClass())); + + if(record!= null && record.getType() != null){ + startService.putExtra(TransportConstants.START_ROUTER_SERVICE_TRANSPORT_CONNECTED, record.getType().toString()); + } + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { startService.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); } diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java index bd37d05f6..a66651502 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java @@ -27,6 +27,7 @@ public class TransportConstants { public static final String START_ROUTER_SERVICE_SDL_ENABLED_EXTRA = "sdl_enabled"; public static final String START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE = "package_name"; public static final String START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME = "component_name"; + public static final String START_ROUTER_SERVICE_TRANSPORT_CONNECTED = "transport_connected"; //Extra for the transport that just connected public static final String START_ROUTER_SERVICE_SDL_ENABLED_PING = "ping"; @Deprecated public static final String FORCE_TRANSPORT_CONNECTED = "force_connect"; //This is legacy, do not refactor this. diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java index db818f7ef..38df218b2 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java @@ -82,7 +82,7 @@ public class TransportManager { config.service = SdlBroadcastReceiver.consumeQueuedRouterService(); } - RouterServiceValidator validator = new RouterServiceValidator(config.context,config.service); + RouterServiceValidator validator = new RouterServiceValidator(config); if(validator.validate()){ transport = new TransportBrokerImpl(config.context, config.appId,config.service); }else{ diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java b/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java index 148c16d6b..4b878c2aa 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java @@ -40,10 +40,12 @@ import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Bundle;
+import android.os.Parcelable;
import android.support.annotation.RequiresApi;
import android.util.Log;
import com.smartdevicelink.util.AndroidTools;
+import com.smartdevicelink.util.DebugTool;
import com.smartdevicelink.util.SdlAppInfo;
import com.smartdevicelink.util.ServiceFinder;
@@ -86,9 +88,12 @@ import static com.smartdevicelink.transport.TransportConstants.FOREGROUND_EXTRA; */
@RequiresApi(12)
public class USBAccessoryAttachmentActivity extends Activity {
- private static final String TAG = USBAccessoryAttachmentActivity.class.getSimpleName();
-
+
+ private static final String TAG = USBAccessoryAttachmentActivity.class.getSimpleName();
+ private static final int USB_SUPPORTED_ROUTER_SERVICE_VERSION = 8;
+
UsbAccessory usbAccessory;
+ Parcelable permissionGranted;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -108,11 +113,8 @@ public class USBAccessoryAttachmentActivity extends Activity { Log.d(TAG, sourceAction + " with action: " + action);
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
- Intent usbAccessoryAttachedIntent = new Intent(USBTransport.ACTION_USB_ACCESSORY_ATTACHED);
- usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_ACCESSORY,intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY));
- usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED,intent.getParcelableExtra(UsbManager.EXTRA_PERMISSION_GRANTED));
-
usbAccessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+ permissionGranted = intent.getParcelableExtra(UsbManager.EXTRA_PERMISSION_GRANTED);
wakeUpRouterService(getApplicationContext());
@@ -131,24 +133,46 @@ public class USBAccessoryAttachmentActivity extends Activity { //We will try to sort the SDL enabled apps and find the one that's been installed the longest
Intent serviceIntent;
List<SdlAppInfo> sdlAppInfoList = AndroidTools.querySdlAppInfo(context, new SdlAppInfo.BestRouterComparator());
+
if (sdlAppInfoList != null && !sdlAppInfoList.isEmpty()) {
+ SdlAppInfo optimalRouterService = sdlAppInfoList.get(0);
+
+ if(optimalRouterService.getRouterServiceVersion() < USB_SUPPORTED_ROUTER_SERVICE_VERSION){
+ // The most optimal router service doesn't support the USB connection
+ // At this point to ensure that USB connection is still possible it might be
+ // worth trying to use the legacy USB transport scheme
+ attemptLegacyUsbConnection();
+ return;
+ }
+
serviceIntent = new Intent();
- serviceIntent.setComponent(sdlAppInfoList.get(0).getRouterServiceComponentName());
+ serviceIntent.setComponent(optimalRouterService.getRouterServiceComponentName());
} else{
Log.d(TAG, "No SDL Router Services found");
Log.d(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!");
+ // At this point to ensure that USB connection is still possible it might be
+ // worth trying to use the legacy USB transport scheme
+ attemptLegacyUsbConnection();
return;
}
serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
+ ComponentName startedService;
try {
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
- context.startService(serviceIntent);
+ startedService = context.startService(serviceIntent);
}else {
serviceIntent.putExtra(FOREGROUND_EXTRA, true);
- context.startForegroundService(serviceIntent);
+ startedService = context.startForegroundService(serviceIntent);
+ }
+ if(startedService == null){
+ // A router service was not started or is not running.
+ DebugTool.logError(TAG + " - Error starting router service. Attempting legacy connection ");
+ attemptLegacyUsbConnection();
+ return;
}
+
//Make sure to send this out for old apps to close down
SdlRouterService.LocalRouterService self = SdlRouterService.getLocalRouterService(serviceIntent, serviceIntent.getComponent());
Intent restart = new Intent(SdlRouterService.REGISTER_NEWER_SERVER_INSTANCE_ACTION);
@@ -183,4 +207,13 @@ public class USBAccessoryAttachmentActivity extends Activity { }
});
}
+
+ private void attemptLegacyUsbConnection(){
+ DebugTool.logInfo("Attempting to send USB connection intent using legacy method");
+ Intent usbAccessoryAttachedIntent = new Intent(USBTransport.ACTION_USB_ACCESSORY_ATTACHED);
+ usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_ACCESSORY, usbAccessory);
+ usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, permissionGranted);
+ AndroidTools.sendExplicitBroadcast(getApplicationContext(),usbAccessoryAttachedIntent,null);
+ finish();
+ }
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransportConfig.java b/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransportConfig.java index 0023c153a..b819a6844 100644 --- a/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransportConfig.java +++ b/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransportConfig.java @@ -5,28 +5,78 @@ import com.smartdevicelink.transport.enums.TransportType; import android.content.Context;
import android.hardware.usb.UsbAccessory;
+/**
+ * <b>NOTE: </b> This should no longer be used. See the MultplexTransportConfig and guides to
+ * understand how to implement USB multiplexing. This class and method of USB connection will be
+ * removed in the next major release. If a router service is available to handle multiplexing of the
+ * usb transport it will be used, and this app will connect to whatever router service hosts the USB
+ * connection.
+ * @see MultiplexTransportConfig
+ */
@Deprecated
public class USBTransportConfig extends BaseTransportConfig {
private Context mainActivity = null;
private UsbAccessory usbAccessory = null;
private Boolean queryUsbAcc = true;
-
+
+ /**
+ * <b>NOTE: </b> This should no longer be used. See the MultplexTransportConfig and guides to
+ * understand how to implement USB multiplexing. This class and method of USB connection will be
+ * removed in the next major release. If a router service is available to handle multiplexing of the
+ * usb transport it will be used, and this app will connect to whatever router service hosts the USB
+ * connection.
+ * @param mainActivity context used to start USB transport
+ * @see MultiplexTransportConfig
+ */
public USBTransportConfig (Context mainActivity) {
this.mainActivity = mainActivity;
}
-
+
+ /**
+ * <b>NOTE: </b> This should no longer be used. See the MultplexTransportConfig and guides to
+ * understand how to implement USB multiplexing. This class and method of USB connection will be
+ * removed in the next major release. If a router service is available to handle multiplexing of the
+ * usb transport it will be used, and this app will connect to whatever router service hosts the USB
+ * connection.
+ * @param mainActivity context used to start USB transport
+ * @param usbAccessory the accessory that was given to this app
+ * @see MultiplexTransportConfig
+ */
public USBTransportConfig (Context mainActivity, UsbAccessory usbAccessory) {
this.mainActivity = mainActivity;
this.usbAccessory = usbAccessory;
}
-
+
+ /**
+ * <b>NOTE: </b> This should no longer be used. See the MultplexTransportConfig and guides to
+ * understand how to implement USB multiplexing. This class and method of USB connection will be
+ * removed in the next major release. If a router service is available to handle multiplexing of the
+ * usb transport it will be used, and this app will connect to whatever router service hosts the USB
+ * connection.
+ * @param mainActivity context used to start USB transport
+ * @param shareConnection enable other sessions on this app to use this USB connection
+ * @param queryUsbAcc attempt to query the USB accessory if none is provided
+ * @see MultiplexTransportConfig
+ */
public USBTransportConfig (Context mainActivity, boolean shareConnection, boolean queryUsbAcc) {
this.mainActivity = mainActivity;
this.queryUsbAcc = queryUsbAcc;
super.shareConnection = shareConnection;
}
-
+
+ /**
+ * <b>NOTE: </b> This should no longer be used. See the MultplexTransportConfig and guides to
+ * understand how to implement USB multiplexing. This class and method of USB connection will be
+ * removed in the next major release. If a router service is available to handle multiplexing of the
+ * usb transport it will be used, and this app will connect to whatever router service hosts the USB
+ * connection.
+ * @param mainActivity context used to start USB transport
+ * @param usbAccessory the accessory that was given to this app
+ * @param shareConnection enable other sessions on this app to use this USB connection
+ * @param queryUsbAcc attempt to query the USB accessory if none is provided
+ * @see MultiplexTransportConfig
+ */
public USBTransportConfig (Context mainActivity, UsbAccessory usbAccessory, boolean shareConnection, boolean queryUsbAcc) {
this.mainActivity = mainActivity;
this.queryUsbAcc = queryUsbAcc;
|