summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Grover <joeygrover@gmail.com>2016-09-27 14:26:08 -0400
committerGitHub <noreply@github.com>2016-09-27 14:26:08 -0400
commit503249159fae9bb9e31b4a4d1ee2fc6a82c567cf (patch)
tree38083e31eb8bbff21006a21174af64891062c288
parenta5139a51cbc708d8ff4d1c64c3114f0d59f362e6 (diff)
parent3688c6c1e3d60df91e0a795f3820a2699930a32a (diff)
downloadsdl_android-503249159fae9bb9e31b4a4d1ee2fc6a82c567cf.tar.gz
Merge pull request #330 from smartdevicelink/feature/multiplexing_cleanup
Multiplexing cleanup
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java10
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/MultiplexBluetoothTransport.java7
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransport.java8
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java12
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java97
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/SdlPsm.java7
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java200
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java17
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/TransportBroker.java87
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/transport/TransportConstants.java13
-rw-r--r--sdl_android_lib/src/com/smartdevicelink/util/DebugTool.java82
11 files changed, 350 insertions, 190 deletions
diff --git a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
index e6472f279..c9a5c13f2 100644
--- a/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
+++ b/sdl_android_lib/src/com/smartdevicelink/SdlConnection/SdlConnection.java
@@ -102,7 +102,6 @@ public class SdlConnection implements IProtocolListener, ITransportListener {
cachedMultiConfig.setService(null);
}
enableLegacyMode(true,TransportType.BLUETOOTH); //We will use legacy bluetooth connection for this attempt
- Log.d(TAG, "Legacy transport : " + legacyTransportRequest);
}
}
@@ -110,7 +109,6 @@ public class SdlConnection implements IProtocolListener, ITransportListener {
(transportConfig.getTransportType() == TransportType.MULTIPLEX)){
_transport = new MultiplexTransport((MultiplexTransportConfig)transportConfig,this);
}else if(isLegacyModeEnabled() && legacyTransportRequest == TransportType.BLUETOOTH){
- Log.d(TAG, "Creating legacy bluetooth connection");
_transport = new BTTransport(this, true);
}else if(transportConfig.getTransportType() == TransportType.BLUETOOTH){
_transport = new BTTransport(this,((BTTransportConfig)transportConfig).getKeepSocketActive());
@@ -529,22 +527,20 @@ public class SdlConnection implements IProtocolListener, ITransportListener {
MultiplexTransport multi = ((MultiplexTransport)_transport);
MultiplexTransportConfig config = multi.getConfig();
ComponentName tempCompName = SdlBroadcastReceiver.consumeQueuedRouterService();
- //Log.d(TAG, "Consumed component name: " +tempCompName );
if(config.getService().equals(tempCompName)){ //If this is the same service that just connected that we are already looking at. Attempt to reconnect
if(!multi.getIsConnected() && multi.isDisconnecting() ){ //If we aren't able to force a connection it means the
- //Log.d(TAG, "Recreating our multiplexing transport");
_transport = new MultiplexTransport(config,this);
try {
startTransport();
} catch (SdlException e) {
e.printStackTrace();
}
- }//else{Log.w(TAG, "Guess we're just calling it a day");}
+ }
}else if(tempCompName!=null){
//We have a conflicting service request
Log.w(TAG, "Conflicting services. Disconnecting from current and connecting to new");
- Log.w(TAG, "Old service " + config.getService().toShortString());
- Log.w(TAG, "New Serivce " + tempCompName.toString());
+ //Log.w(TAG, "Old service " + config.getService().toShortString());
+ //Log.w(TAG, "New Serivce " + tempCompName.toString());
multi.disconnect();
config.setService(tempCompName);
_transport = new MultiplexTransport(config,this);
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexBluetoothTransport.java b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
index 08fe98586..95746b05a 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexBluetoothTransport.java
@@ -49,7 +49,7 @@ public class MultiplexBluetoothTransport {
private static final String TAG = "Bluetooth Transport";
private static final UUID SERVER_UUID= new UUID(0x936DA01F9ABD4D9DL, 0x80C702AF85C822A8L);
// Name for the SDP record when creating server socket
- private static final String NAME_SECURE =" SdlProxy";// = "LIVIO_CONNECT";
+ private static final String NAME_SECURE =" SdlRouterService";
protected static final String SHARED_PREFS = "sdl.bluetoothprefs";
@@ -696,7 +696,7 @@ public class MultiplexBluetoothTransport {
//Log.d(TAG, "Creating a Connected - Write Thread");
mmSocket = socket;
OutputStream tmpOut = null;
- setName(" Livio Bluetooth Write Thread");
+ setName("SDL Router BT Write Thread");
// Get the BluetoothSocket input and output streams
try {
tmpOut = socket.getOutputStream();
@@ -731,7 +731,6 @@ public class MultiplexBluetoothTransport {
public synchronized void cancel() {
try {
- Log.d(TAG, "Calling Cancel in the write thread");
if(mmOutStream!=null){
mmOutStream.flush();
mmOutStream.close();
@@ -756,7 +755,7 @@ public class MultiplexBluetoothTransport {
//Log.d(TAG, "Creating a Connected - Read Thread");
mmSocket = socket;
InputStream tmpIn = null;
- setName(" Livio Bluetooth Read Thread");
+ setName("SDL Router BT Read Thread");
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransport.java b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransport.java
index e82bcd209..39c401e1f 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransport.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/MultiplexTransport.java
@@ -15,7 +15,7 @@ import com.smartdevicelink.transport.enums.TransportType;
public class MultiplexTransport extends SdlTransport{
private final static String TAG = "Multiplex Transport";
- private String sComment = "I'm_a_little_teapot";
+ private String sComment = "Multiplexing";
TransportBrokerThread brokerThread;
protected boolean isDisconnecting = false;
@@ -213,7 +213,7 @@ public class MultiplexTransport extends SdlTransport{
public void run() {
Looper.prepare();
- if(broker==null){Log.d("JOEY", "Starting broker");
+ if(broker==null){
synchronized(this){
initTransportBroker();
if(queueStart){
@@ -228,7 +228,6 @@ public class MultiplexTransport extends SdlTransport{
}
threadLooper = Looper.myLooper();
Looper.loop();
- Log.i(TAG, "Looper has finished. Thread should be sutting down");
}
@@ -242,9 +241,8 @@ public class MultiplexTransport extends SdlTransport{
Log.d(TAG, "On transport connected...");
if(!connected){
connected = true;
- Log.d(TAG, "Handling transport connected");
handleTransportConnected();
- }else{Log.d(TAG, "Already connected");}
+ }//else{Log.d(TAG, "Already connected");}
return true;
}else{
try{
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java b/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java
index 5809a19aa..3c5b71c5e 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/RouterServiceValidator.java
@@ -35,7 +35,7 @@ import com.smartdevicelink.util.HttpRequestTask.HttpRequestTaskCallback;
*
*/
public class RouterServiceValidator {
- private static final String TAG = "PackageCheckUtl";
+ private static final String TAG = "RSVP";
public static final String ROUTER_SERVICE_PACKAGE = "com.sdl.router";
private static final String REQUEST_PREFIX = "https://woprjr.smartdevicelink.com/api/1/applications/queryTrustedRouters";
@@ -116,7 +116,7 @@ public class RouterServiceValidator {
}
}
- Log.d(TAG, "Checking app package: " + service.getClassName());
+ //Log.d(TAG, "Checking app package: " + service.getClassName());
packageName = this.appPackageForComponentName(service, pm);
@@ -328,10 +328,9 @@ public class RouterServiceValidator {
intent.setAction("sdl.router.startservice");
List<ResolveInfo> infoList = packageManager.queryBroadcastReceivers(intent, 0);
if(infoList!=null){
- Log.i(TAG, "Number of SDL apps: " + infoList.size());
String packageName;
for(ResolveInfo info : infoList){
- Log.i(TAG, "SDL apps: " + info.activityInfo.packageName);
+ //Log.i(TAG, "SDL apps: " + info.activityInfo.packageName);
packageName = info.activityInfo.packageName;
try {
apps.add(new SdlApp(packageName,packageManager.getPackageInfo(packageName,0).versionCode));
@@ -362,7 +361,6 @@ public class RouterServiceValidator {
}
if(!forceRefresh && (System.currentTimeMillis()-getTrustedAppListTimeStamp(context))<REFRESH_TRUSTED_APP_LIST_TIME){
- Log.d(TAG, "Don't need to get new list");
//Our list should still be ok for now so we will skip the request
pendingListRefresh = false;
return false;
@@ -393,15 +391,13 @@ public class RouterServiceValidator {
try {object.put(JSON_PUT_ARRAY_TAG, array);} catch (JSONException e) {e.printStackTrace();}
- Log.d(TAG, "Request of apps: " + object.toString());
-
if (cb == null) {
cb = new HttpRequestTaskCallback() {
@Override
public void httpCallComplete(String response) {
// Might want to check if this list is ok
- Log.d(TAG, "APPS! " + response);
+ //Log.d(TAG, "APPS! " + response);
setTrustedList(context, response);
pendingListRefresh = false;
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java
index 1686285c9..ae07046c5 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlBroadcastReceiver.java
@@ -1,6 +1,8 @@
package com.smartdevicelink.transport;
import java.util.Locale;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentLinkedQueue;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
@@ -9,8 +11,6 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
@@ -29,7 +29,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
public static final String TRANSPORT_GLOBAL_PREFS = "SdlTransportPrefs";
public static final String IS_TRANSPORT_CONNECTED = "isTransportConnected";
- public static ComponentName runningBluetoothServicePackage = null;
+ public static Vector<ComponentName> runningBluetoothServicePackage = null;
@SuppressWarnings("rawtypes")
private static Class localRouterClass;
@@ -72,15 +72,15 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
String packageName = intent.getStringExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE);
ComponentName componentName = intent.getParcelableExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME);
if(componentName!=null){
- Log.v(TAG, "SDL enabled by router service from " + packageName + " compnent package " + componentName.getPackageName() + " - " + componentName.getClassName());
+ //Log.v(TAG, "SDL enabled by router service from " + packageName + " compnent package " + componentName.getPackageName() + " - " + componentName.getClassName());
RouterServiceValidator vlad = new RouterServiceValidator(context,componentName);
if(vlad.validate()){
- Log.d(TAG, "Router service trusted!");
+ //Log.d(TAG, "Router service trusted!");
queuedService = componentName;
intent.setAction("com.sdl.noaction"); //Replace what's there so we do go into some unintended loop
onSdlEnabled(context, intent);
}else{
- Log.e(TAG, "RouterService was not trusted. Ignoring intent from : "+ componentName.getClassName());
+ Log.w(TAG, "RouterService was not trusted. Ignoring intent from : "+ componentName.getClassName());
}
}
@@ -93,7 +93,6 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
return;
}else if(intent.getBooleanExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA, false)){
//We were told to wake up our router services
- Log.d(TAG, "Starting router service off ping");
boolean altServiceWake = intent.getBooleanExtra(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT, false);
didStart = wakeUpRouterService(context, false,altServiceWake );
@@ -113,7 +112,6 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
return;
}else if(state == BluetoothAdapter.STATE_TURNING_ON){
//We started bluetooth, we should check for a new valid router list
- Log.d(TAG, "Attempting to get list of approved router services");
RouterServiceValidator.createTrustedListRequest(context,true);
}
}
@@ -121,7 +119,6 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
if(localRouterClass!=null){ //If there is a supplied router service lets run some logic regarding starting one
if(!didStart){
- Log.d(TAG, "Waking up router service");
didStart = wakeUpRouterService(context, true,false);
}
@@ -138,10 +135,8 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
}
private boolean wakeUpRouterService(Context context, boolean ping, boolean altTransportWake){
- Log.d(TAG, "Waking up router service");
if(!isRouterServiceRunning(context, ping)){
//If there isn't a service running we should try to start one
- Log.i(TAG, "Attempting to start an instance of the Router Service");
//The under class should have implemented this....
//So let's start up our service since no copy is running
@@ -152,18 +147,21 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
context.startService(serviceIntent);
return true;
}else{
- Log.i(TAG, "An instance of the Router Service is already running");
- if(altTransportWake){
+ if(altTransportWake && runningBluetoothServicePackage!=null && runningBluetoothServicePackage.size()>0){
Intent serviceIntent = new Intent();
- serviceIntent.setComponent(runningBluetoothServicePackage);
serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
- context.startService(serviceIntent);
+ //context.startService(serviceIntent);
+ for(ComponentName compName: runningBluetoothServicePackage){
+ serviceIntent.setComponent(compName);
+ context.startService(serviceIntent);
+
+ }
return true;
}
return false;
}
}
-
+
/**
* Determines if an instance of the Router Service is currently running on the device.
* @param context A context to access Android system services through.
@@ -175,13 +173,18 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
Log.e(TAG, "Can't look for router service, context supplied was null");
return false;
}
- Log.d(TAG, "Looking for Service: "+ SDL_ROUTER_SERVICE_CLASS_NAME);
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ if(runningBluetoothServicePackage==null){
+ runningBluetoothServicePackage = new Vector<ComponentName>();
+ }else{
+ runningBluetoothServicePackage.clear();
+ }
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
//We will check to see if it contains this name, should be pretty specific
//Log.d(TAG, "Found Service: "+ service.service.getClassName());
if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME)) {
- runningBluetoothServicePackage = service.service; //Store which instance is running
+
+ runningBluetoothServicePackage.add(service.service); //Store which instance is running
if(pingService){
Intent intent = new Intent();
intent.setClassName(service.service.getPackageName(), service.service.getClassName());
@@ -197,20 +200,63 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
}
/**
+ * This call will reach out to all SDL related router services to check if they're connected. If a the router service is connected, it will react by pinging all clients. This receiver will then
+ * receive that ping and if the router service is trusted, the onSdlEnabled method will be called.
+ * @param context
+ */
+ public static void queryForConnectedService(Context context){
+ //Leverage existing call. Include ping bit
+ requestTransportStatus(context,null,true);
+ }
+ /**
* If a Router Service is running, this method determines if that service is connected to a device over some form of transport.
* @param context A context to access Android system services through. If null is passed, this will always return false
* @param callback Use this callback to find out if the router service is connected or not.
*/
- public static void requestTransportStatus(Context context, SdlRouterStatusProvider.ConnectedStatusCallback callback){
- Log.d(TAG, "Checking to see if router service is transport connected");
+ public static void requestTransportStatus(Context context, final SdlRouterStatusProvider.ConnectedStatusCallback callback){
+ requestTransportStatus(context,callback,false);
+ }
+
+ private static void requestTransportStatus(Context context, final SdlRouterStatusProvider.ConnectedStatusCallback callback, final boolean triggerRouterServicePing){
if(context == null){
if(callback!=null){
- callback.onConnectionStatusUpdate(false, context);
+ callback.onConnectionStatusUpdate(false, null,context);
}
+ return;
}
- if(isRouterServiceRunning(context,false)){ //So there is a service up, let's see if it's connected
- SdlRouterStatusProvider provider = new SdlRouterStatusProvider(context,runningBluetoothServicePackage,callback);
- provider.checkIsConnected();
+ if(isRouterServiceRunning(context,false) && !runningBluetoothServicePackage.isEmpty()){ //So there is a service up, let's see if it's connected
+ final ConcurrentLinkedQueue<ComponentName> list = new ConcurrentLinkedQueue<ComponentName>(runningBluetoothServicePackage);
+ if(runningBluetoothServicePackage.size()>0){ //TODO for testing do this for all cases
+ final SdlRouterStatusProvider.ConnectedStatusCallback sdlBrCallback = new SdlRouterStatusProvider.ConnectedStatusCallback() {
+
+ @Override
+ public void onConnectionStatusUpdate(boolean connected, ComponentName service,Context context) {
+ if(!connected && !list.isEmpty()){
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider(context,list.poll(), this);
+ if(triggerRouterServicePing){provider.setFlags(TransportConstants.ROUTER_STATUS_FLAG_TRIGGER_PING); }
+ provider.checkIsConnected();
+ }else{
+ Log.d(TAG, service.getPackageName() + " is connected = " + connected);
+ if(callback!=null){
+ callback.onConnectionStatusUpdate(connected, service,context);
+ }
+ list.clear();
+ }
+
+ }
+ };
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider(context,list.poll(),sdlBrCallback);
+ if(triggerRouterServicePing){
+ provider.setFlags(TransportConstants.ROUTER_STATUS_FLAG_TRIGGER_PING);
+ }
+ provider.checkIsConnected();
+ }else{ //If only one service is running, just check that
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider(context,runningBluetoothServicePackage.get(0),callback);
+ if(triggerRouterServicePing){
+ provider.setFlags(TransportConstants.ROUTER_STATUS_FLAG_TRIGGER_PING);
+ }
+ provider.checkIsConnected();
+ }
}else{
Log.w(TAG, "Router service isn't running, returning false.");
if(BluetoothAdapter.getDefaultAdapter()!=null && BluetoothAdapter.getDefaultAdapter().isEnabled()){
@@ -220,10 +266,11 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
context.sendBroadcast(serviceIntent);
}
if(callback!=null){
- callback.onConnectionStatusUpdate(false, context);
+ callback.onConnectionStatusUpdate(false, null,context);
}
}
}
+
public static ComponentName consumeQueuedRouterService(){
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlPsm.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlPsm.java
index b04b4453b..d6a9840ae 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlPsm.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlPsm.java
@@ -195,14 +195,17 @@ public class SdlPsm{
if(dataLength==0){
return FINISHED_STATE; //We are done if we don't have any payload
}
- payload = new byte[dataLength];
+ try{
+ payload = new byte[dataLength];
+ }catch(OutOfMemoryError oom){
+ return ERROR_STATE;
+ }
dumpSize = dataLength;
return DATA_PUMP_STATE;
case DATA_PUMP_STATE:
payload[dataLength-dumpSize] = rawByte;
dumpSize--;
- //Log.trace(TAG,rawByte + " read. Data Length remaining: " + dumpSize);
//Do we have any more bytes to read in?
if(dumpSize>0){
return DATA_PUMP_STATE;
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java
index 7519dce0e..c6c511dc4 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterService.java
@@ -5,6 +5,7 @@ import static com.smartdevicelink.transport.TransportConstants.FORMED_PACKET_EXT
import static com.smartdevicelink.transport.TransportConstants.HARDWARE_DISCONNECTED;
import static com.smartdevicelink.transport.TransportConstants.SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME;
+import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -293,16 +294,23 @@ public class SdlRouterService extends Service{
/**
* Target we publish for clients to send messages to RouterHandler.
*/
- final Messenger routerMessenger = new Messenger(new RouterHandler());
+ final Messenger routerMessenger = new Messenger(new RouterHandler(this));
/**
* Handler of incoming messages from clients.
*/
- class RouterHandler extends Handler {
+ static class RouterHandler extends Handler {
+ WeakReference<SdlRouterService> provider;
+
+ public RouterHandler(SdlRouterService provider){
+ this.provider = new WeakReference<SdlRouterService>(provider);
+ }
+
@Override
public void handleMessage(Message msg) {
final Bundle receivedBundle = msg.getData();
Bundle returnBundle;
+ final SdlRouterService service = this.provider.get();
switch (msg.what) {
case TransportConstants.ROUTER_REQUEST_BT_CLIENT_CONNECT:
@@ -311,14 +319,14 @@ public class SdlRouterService extends Service{
//Log.d(TAG,"Attempting to connect as bt client");
BluetoothDevice device = receivedBundle.getParcelable(BluetoothDevice.EXTRA_DEVICE);
connectAsClient = true;
- if(device==null || !bluetoothConnect(device)){
+ if(device==null || !service.bluetoothConnect(device)){
Log.e(TAG, "Unable to connect to bluetooth device");
connectAsClient = false;
}
}
//**************** We don't break here so we can let the app register as well
case TransportConstants.ROUTER_REGISTER_CLIENT: //msg.arg1 is appId
- pingClients();
+ //pingClients();
Message message = Message.obtain();
message.what = TransportConstants.ROUTER_REGISTER_CLIENT_RESPONSE;
message.arg1 = TransportConstants.REGISTRATION_RESPONSE_SUCESS;
@@ -335,7 +343,7 @@ public class SdlRouterService extends Service{
}
break;
}
- if(SdlRouterService.this.legacyModeEnabled){
+ if(service.legacyModeEnabled){
Log.w(TAG, "Unable to register app as legacy mode is enabled");
if(msg.replyTo!=null){
message.arg1 = TransportConstants.REGISTRATION_RESPONSE_DENIED_LEGACY_MODE_ENABLED;
@@ -348,21 +356,21 @@ public class SdlRouterService extends Service{
break;
}
- RegisteredApp app = new RegisteredApp(appId,msg.replyTo);
- synchronized(REGISTERED_APPS_LOCK){
+ RegisteredApp app = service.new RegisteredApp(appId,msg.replyTo);
+ synchronized(service.REGISTERED_APPS_LOCK){
RegisteredApp old = registeredApps.put(app.getAppId(), app);
if(old!=null){
Log.w(TAG, "Replacing already existing app with this app id");
- removeAllSessionsForApp(old, true);
+ service.removeAllSessionsForApp(old, true);
old.close();
}
}
- onAppRegistered(app);
+ service.onAppRegistered(app);
returnBundle = new Bundle();
//Add params if connected
- if(SdlRouterService.this.isTransportConnected){
- returnBundle.putString(TransportConstants.HARDWARE_CONNECTED, SdlRouterService.this.connectedTransportType.name());
+ if(service.isTransportConnected){
+ returnBundle.putString(TransportConstants.HARDWARE_CONNECTED, service.connectedTransportType.name());
if(MultiplexBluetoothTransport.currentlyConnectedDevice!=null){
returnBundle.putString(CONNECTED_DEVICE_STRING_EXTRA_NAME, MultiplexBluetoothTransport.currentlyConnectedDevice);
}
@@ -374,7 +382,7 @@ public class SdlRouterService extends Service{
int result = app.sendMessage(message);
if(result == RegisteredApp.SEND_MESSAGE_ERROR_MESSENGER_DEAD_OBJECT){
- synchronized(REGISTERED_APPS_LOCK){
+ synchronized(service.REGISTERED_APPS_LOCK){
registeredApps.remove(appId);
}
}
@@ -383,17 +391,17 @@ public class SdlRouterService extends Service{
long appIdToUnregister = receivedBundle.getLong(TransportConstants.APP_ID_EXTRA, -1);
Log.i(TAG, "Unregistering client: " + appIdToUnregister);
RegisteredApp unregisteredApp = null;
- synchronized(REGISTERED_APPS_LOCK){
+ synchronized(service.REGISTERED_APPS_LOCK){
unregisteredApp = registeredApps.remove(appIdToUnregister);
}
Message response = Message.obtain();
response.what = TransportConstants.ROUTER_UNREGISTER_CLIENT_RESPONSE;
if(unregisteredApp == null){
response.arg1 = TransportConstants.UNREGISTRATION_RESPONSE_FAILED_APP_ID_NOT_FOUND;
- removeAllSessionsWithAppId(appIdToUnregister);
+ service.removeAllSessionsWithAppId(appIdToUnregister);
}else{
response.arg1 = TransportConstants.UNREGISTRATION_RESPONSE_SUCESS;
- removeAllSessionsForApp(unregisteredApp,false);
+ service.removeAllSessionsForApp(unregisteredApp,false);
}
Log.i(TAG, "Unregistering client response: " + response.arg1 );
try {
@@ -417,7 +425,7 @@ public class SdlRouterService extends Service{
Long buffAppId = receivedBundle.getLong(TransportConstants.APP_ID_EXTRA);
RegisteredApp buffApp = null;
if(buffAppId!=null){
- synchronized(REGISTERED_APPS_LOCK){
+ synchronized(service.REGISTERED_APPS_LOCK){
buffApp = registeredApps.get(buffAppId);
}
}
@@ -425,13 +433,13 @@ public class SdlRouterService extends Service{
if(buffApp !=null){
buffApp.handleIncommingClientMessage(receivedBundle);
}else{
- writeBytesToTransport(receivedBundle);
+ service.writeBytesToTransport(receivedBundle);
}
}
}
};
- if(packetExecuter!=null){
- packetExecuter.execute(packetRun);
+ if(service.packetExecuter!=null){
+ service.packetExecuter.execute(packetRun);
}
}
break;
@@ -440,7 +448,7 @@ public class SdlRouterService extends Service{
Message extraSessionResponse = Message.obtain();
extraSessionResponse.what = TransportConstants.ROUTER_REQUEST_NEW_SESSION_RESPONSE;
if(appIdRequesting>0){
- synchronized(REGISTERED_APPS_LOCK){
+ synchronized(service.REGISTERED_APPS_LOCK){
if(registeredApps!=null){
RegisteredApp appRequesting = registeredApps.get(appIdRequesting);
if(appRequesting!=null){
@@ -465,12 +473,12 @@ public class SdlRouterService extends Service{
case TransportConstants.ROUTER_REMOVE_SESSION:
long appIdWithSession = receivedBundle.getLong(TransportConstants.APP_ID_EXTRA, -1);
long sessionId = receivedBundle.getLong(TransportConstants.SESSION_ID_EXTRA, -1);
- removeSessionFromMap((int)sessionId);
+ service.removeSessionFromMap((int)sessionId);
Message removeSessionResponse = Message.obtain();
removeSessionResponse.what = TransportConstants.ROUTER_REMOVE_SESSION_RESPONSE;
if(appIdWithSession>0){
if(sessionId>=0){
- synchronized(REGISTERED_APPS_LOCK){
+ synchronized(service.REGISTERED_APPS_LOCK){
if(registeredApps!=null){
RegisteredApp appRequesting = registeredApps.get(appIdWithSession);
if(appRequesting!=null){
@@ -508,15 +516,23 @@ public class SdlRouterService extends Service{
/**
* Target we publish for alternative transport (USB) clients to send messages to RouterHandler.
*/
- final Messenger altTransportMessenger = new Messenger(new AltTransportHandler());
+ final Messenger altTransportMessenger = new Messenger(new AltTransportHandler(this));
/**
* Handler of incoming messages from an alternative transport (USB).
*/
- class AltTransportHandler extends Handler {
- ClassLoader loader = getClass().getClassLoader();
+ static class AltTransportHandler extends Handler {
+ ClassLoader loader;
+ WeakReference<SdlRouterService> provider;
+
+ public AltTransportHandler(SdlRouterService provider){
+ this.provider = new WeakReference<SdlRouterService>(provider);
+ loader = getClass().getClassLoader();
+ }
+
@Override
public void handleMessage(Message msg) {
+ SdlRouterService service = this.provider.get();
Bundle receivedBundle = msg.getData();
switch(msg.what){
case TransportConstants.HARDWARE_CONNECTION_EVENT:
@@ -526,8 +542,8 @@ public class SdlRouterService extends Service{
&& altTransportService.equals(msg.replyTo)){
//The same transport that was connected to the router service is now telling us it's disconnected. Let's inform clients and clear our saved messenger
altTransportService = null;
- onTransportDisconnected(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_DISCONNECTED)));
- shouldServiceRemainOpen(null); //this will close the service if bluetooth is not available
+ service.onTransportDisconnected(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_DISCONNECTED)));
+ service.shouldServiceRemainOpen(null); //this will close the service if bluetooth is not available
}
}else if(receivedBundle.containsKey(TransportConstants.HARDWARE_CONNECTED)){
Message retMsg = Message.obtain();
@@ -539,15 +555,15 @@ public class SdlRouterService extends Service{
}
altTransportService = msg.replyTo;
//Clear out the timer to make sure the service knows we're good to go
- if(altTransportTimerHandler!=null && altTransportTimerRunnable!=null){
- altTransportTimerHandler.removeCallbacks(altTransportTimerRunnable);
+ if(service.altTransportTimerHandler!=null && service.altTransportTimerRunnable!=null){
+ service.altTransportTimerHandler.removeCallbacks(service.altTransportTimerRunnable);
}
- altTransportTimerHandler = null;
- altTransportTimerRunnable = null;
+ service.altTransportTimerHandler = null;
+ service.altTransportTimerRunnable = null;
//Let the alt transport know they are good to go
retMsg.arg1 = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_RESPONSE_SUCESS;
- onTransportConnected(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_CONNECTED)));
+ service.onTransportConnected(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_CONNECTED)));
}else{ //There seems to be some other transport connected
//Error
retMsg.arg1 = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_ALREADY_CONNECTED;
@@ -566,7 +582,7 @@ public class SdlRouterService extends Service{
if(receivedBundle.containsKey(TransportConstants.FORMED_PACKET_EXTRA_NAME)){
SdlPacket packet = receivedBundle.getParcelable(TransportConstants.FORMED_PACKET_EXTRA_NAME);
if(packet!=null){
- onPacketRead(packet);
+ service.onPacketRead(packet);
}else{
Log.w(TAG, "Received null packet from alt transport service");
}
@@ -584,28 +600,40 @@ public class SdlRouterService extends Service{
/**
* Target we publish for alternative transport (USB) clients to send messages to RouterHandler.
*/
- final Messenger routerStatusMessenger = new Messenger(new RouterStatusHandler());
+ final Messenger routerStatusMessenger = new Messenger(new RouterStatusHandler(this));
/**
* Handler of incoming messages from an alternative transport (USB).
*/
- class RouterStatusHandler extends Handler {
- ClassLoader loader = getClass().getClassLoader();
+ static class RouterStatusHandler extends Handler {
+ WeakReference<SdlRouterService> provider;
+
+ public RouterStatusHandler(SdlRouterService provider){
+ this.provider = new WeakReference<SdlRouterService>(provider);
+ }
+
@Override
public void handleMessage(Message msg) {
+ SdlRouterService service = this.provider.get();
switch(msg.what){
case TransportConstants.ROUTER_STATUS_CONNECTED_STATE_REQUEST:
- if(msg.replyTo==null){
- break;
+ int flags = msg.arg1;
+ if(msg.replyTo!=null){
+ Message message = Message.obtain();
+ message.what = TransportConstants.ROUTER_STATUS_CONNECTED_STATE_RESPONSE;
+ message.arg1 = (service.isTransportConnected == true) ? 1 : 0;
+ try {
+ msg.replyTo.send(message);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ if(service.isTransportConnected && ((TransportConstants.ROUTER_STATUS_FLAG_TRIGGER_PING & flags) == TransportConstants.ROUTER_STATUS_FLAG_TRIGGER_PING)){
+ if(service.pingIntent == null){
+ service.initPingIntent();
+ }
+ service.getBaseContext().sendBroadcast(service.pingIntent);
}
- Message message = Message.obtain();
- message.what = TransportConstants.ROUTER_STATUS_CONNECTED_STATE_RESPONSE;
- message.arg1 = (isTransportConnected == true) ? 1 : 0;
- try {
- msg.replyTo.send(message);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
break;
default:
Log.w(TAG, "Unsopported request: " + msg.what);
@@ -628,7 +656,9 @@ public class SdlRouterService extends Service{
}
String requestType = intent.getAction();//intent.getIntExtra(TransportConstants.ROUTER_BIND_REQUEST_TYPE_EXTRA, TransportConstants.BIND_REQUEST_TYPE_CLIENT);
if(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT.equals(requestType)){
- return this.altTransportMessenger.getBinder();
+ if(0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)){ //Only allow alt transport in debug mode
+ return this.altTransportMessenger.getBinder();
+ }
}else if(TransportConstants.BIND_REQUEST_TYPE_CLIENT.equals(requestType)){
return this.routerMessenger.getBinder();
}else if(TransportConstants.BIND_REQUEST_TYPE_STATUS.equals(requestType)){
@@ -748,14 +778,11 @@ public class SdlRouterService extends Service{
}
public void startUpSequence(){
- IntentFilter stateChangeFilter = new IntentFilter("android.bluetooth.adapter.action.STATE_CHANGED");
- stateChangeFilter.addAction("android.bluetooth.device.action.CLASS_CHANGED");
- IntentFilter disconnectFilter1 = new IntentFilter("android.bluetooth.device.action.ACL_DISCONNECTED");
- IntentFilter disconnectFilter2 = new IntentFilter("android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED");
-
- registerReceiver(mListenForDisconnect,stateChangeFilter );
- registerReceiver(mListenForDisconnect,disconnectFilter1 );
- registerReceiver(mListenForDisconnect,disconnectFilter2 );
+ IntentFilter disconnectFilter = new IntentFilter("android.bluetooth.adapter.action.STATE_CHANGED");
+ disconnectFilter.addAction("android.bluetooth.device.action.CLASS_CHANGED");
+ disconnectFilter.addAction("android.bluetooth.device.action.ACL_DISCONNECTED");
+ disconnectFilter.addAction("android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED");
+ registerReceiver(mListenForDisconnect,disconnectFilter );
IntentFilter filter = new IntentFilter();
filter.addAction(REGISTER_WITH_ROUTER_ACTION);
@@ -996,13 +1023,11 @@ public class SdlRouterService extends Service{
Log.d(TAG, "Not starting own bluetooth during legacy mode");
return;
}
- Log.i(TAG, "Iniitializing Bluetooth Serial Class");
+ Log.i(TAG, "Iniitializing bluetooth transport");
//init serial service
if(mSerialService ==null){
- Log.d(TAG, "Local copy of BT Server is null");
mSerialService = MultiplexBluetoothTransport.getBluetoothSerialServerInstance();
if(mSerialService==null){
- Log.d(TAG, "Local copy of BT Server is still null and so is global");
mSerialService = MultiplexBluetoothTransport.getBluetoothSerialServerInstance(mHandlerBT);
}
}
@@ -1073,7 +1098,6 @@ public class SdlRouterService extends Service{
cachedModuleVersion = -1; //Reset our cached version
if(registeredApps== null || registeredApps.isEmpty()){
- Log.w(TAG, "No clients to notify. Sending global notification.");
Intent unregisterIntent = new Intent();
unregisterIntent.putExtra(HARDWARE_DISCONNECTED, type.name());
unregisterIntent.putExtra(TransportConstants.ENABLE_LEGACY_MODE_EXTRA, legacyModeEnabled);
@@ -1175,7 +1199,7 @@ public class SdlRouterService extends Service{
int offset = bundle.getInt(TransportConstants.BYTES_TO_SEND_EXTRA_OFFSET, 0); //If nothing, start at the begining of the array
int count = bundle.getInt(TransportConstants.BYTES_TO_SEND_EXTRA_COUNT, packet.length); //In case there isn't anything just send the whole packet.
if(packet!=null){
- mSerialService.write(packet,offset,count); Log.i(TAG, "Wrote out bytes");
+ mSerialService.write(packet,offset,count);
return true;
}
return false;
@@ -1191,7 +1215,7 @@ public class SdlRouterService extends Service{
private boolean manuallyWriteBytes(byte[] bytes, int offset, int count){
if(mSerialService !=null && mSerialService.getState()==MultiplexBluetoothTransport.STATE_CONNECTED){
if(bytes!=null){
- mSerialService.write(bytes,offset,count);Log.i(TAG, "Wrote out bytes manually");
+ mSerialService.write(bytes,offset,count);
return true;
}
return false;
@@ -1211,7 +1235,6 @@ public class SdlRouterService extends Service{
*/
private boolean sendThroughAltTransport(Bundle bundle){
if(altTransportService!=null){
- Log.d(TAG, "Sending packet through alt transport");
Message msg = Message.obtain();
msg.what = TransportConstants.ROUTER_SEND_PACKET;
msg.setData(bundle);
@@ -1235,7 +1258,6 @@ public class SdlRouterService extends Service{
*/
private boolean sendThroughAltTransport(byte[] bytes, int offset, int count){
if(altTransportService!=null){
- Log.d(TAG, "Sending packet through alt transport");
Message msg = Message.obtain();
msg.what = TransportConstants.ROUTER_SEND_PACKET;
Bundle bundle = new Bundle();
@@ -1321,7 +1343,7 @@ public class SdlRouterService extends Service{
bundle.putParcelable(FORMED_PACKET_EXTRA_NAME, copyPacket);
bundle.putInt(TransportConstants.BYTES_TO_SEND_FLAGS, TransportConstants.BYTES_TO_SEND_FLAG_SDL_PACKET_INCLUDED);
message.setData(bundle);
- Log.d(TAG, "First packet before sending: " + message.getData().toString());
+ //Log.d(TAG, "First packet before sending: " + message.getData().toString());
if(!sendPacketMessageToClient(app, message, version)){
Log.w(TAG, "Error sending first message of split packet to client " + app.appId);
return false;
@@ -1335,7 +1357,7 @@ public class SdlRouterService extends Service{
return false;
}
}
- Log.i(TAG, "Large packet finished being sent");
+ //Log.i(TAG, "Large packet finished being sent");
}
}else{ //If we can't find a session for this packet we just drop the packet
@@ -1550,8 +1572,8 @@ public class SdlRouterService extends Service{
LocalRouterService newestServiceReceived = getLocalBluetoothServiceComapre();
LocalRouterService self = getLocalRouterService(); //We can send in null here, because it should have already been created
- Log.v(TAG, "Self service info " + self);
- Log.v(TAG, "Newest compare to service info " + newestServiceReceived);
+ //Log.v(TAG, "Self service info " + self);
+ //Log.v(TAG, "Newest compare to service info " + newestServiceReceived);
if(newestServiceReceived!=null && self.isNewer(newestServiceReceived)){
Log.d(TAG, "There is a newer version of the Router Service, starting it up");
closing = true;
@@ -1624,8 +1646,8 @@ public class SdlRouterService extends Service{
SparseArray<Long> iter = sessionMap.clone();
int size = iter.size();
for(int i = 0; i<size; i++){
- Log.d(TAG, "Investigating session " +iter.keyAt(i));
- Log.d(TAG, "App id is: " + iter.valueAt(i));
+ //Log.d(TAG, "Investigating session " +iter.keyAt(i));
+ //Log.d(TAG, "App id is: " + iter.valueAt(i));
if(((Long)iter.valueAt(i)).compareTo(appId) == 0){
sessionHashIdMap.remove(iter.keyAt(i));
sessionMap.removeAt(i);
@@ -1644,8 +1666,8 @@ public class SdlRouterService extends Service{
Vector<Long> sessions = app.getSessionIds();
int size = sessions.size(), sessionId;
for(int i=0; i<size;i++){
- Log.d(TAG, "Investigating session " +sessions.get(i).intValue());
- Log.d(TAG, "App id is: " + sessionMap.get(sessions.get(i).intValue()));
+ //Log.d(TAG, "Investigating session " +sessions.get(i).intValue());
+ //Log.d(TAG, "App id is: " + sessionMap.get(sessions.get(i).intValue()));
sessionId = sessions.get(i).intValue();
removeSessionFromMap(sessionId);
if(cleanModule){
@@ -1687,7 +1709,7 @@ public class SdlRouterService extends Service{
}
}
}
- Log.d(TAG, sessionId + " session returning App Id: " + appId);
+ //Log.d(TAG, sessionId + " session returning App Id: " + appId);
return appId;
}
}
@@ -1796,7 +1818,7 @@ public class SdlRouterService extends Service{
peekTask = app.peekNextTask();
if(peekTask!=null){
peekWeight = peekTask.getWeight(currentTime);
- Log.v(TAG, "App " + app.appId +" has a task with weight "+ peekWeight);
+ //Log.v(TAG, "App " + app.appId +" has a task with weight "+ peekWeight);
if(peekWeight>currentPriority){
if(app.queuePaused){
app.notIt();//Reset the timer
@@ -1817,6 +1839,15 @@ public class SdlRouterService extends Service{
return null;
}
+ private void initPingIntent(){
+ pingIntent = new Intent();
+ pingIntent.setAction(START_SERVICE_ACTION);
+ pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_EXTRA, true);
+ pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE, getBaseContext().getPackageName());
+ pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME, new ComponentName(SdlRouterService.this, SdlRouterService.this.getClass()));
+ pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_PING, true);
+ }
+
private void startClientPings(){
synchronized(this){
if(!isTransportConnected){ //If we aren't connected, bail
@@ -1846,12 +1877,7 @@ public class SdlRouterService extends Service{
return;
}
if(pingIntent == null){
- pingIntent = new Intent();
- pingIntent.setAction(START_SERVICE_ACTION);
- pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_EXTRA, true);
- pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE, getBaseContext().getPackageName());
- pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME, new ComponentName(SdlRouterService.this, SdlRouterService.this.getClass()));
- pingIntent.putExtra(TransportConstants.START_ROUTER_SERVICE_SDL_ENABLED_PING, true);
+ initPingIntent();
}
getBaseContext().sendBroadcast(pingIntent);
synchronized(PING_COUNT_LOCK){
@@ -2086,7 +2112,7 @@ public class SdlRouterService extends Service{
public boolean handleIncommingClientMessage(final Bundle receivedBundle){
int flags = receivedBundle.getInt(TransportConstants.BYTES_TO_SEND_FLAGS, TransportConstants.BYTES_TO_SEND_FLAG_NONE);
- Log.d(TAG, "Flags received: " + flags);
+ //Log.d(TAG, "Flags received: " + flags);
if(flags!=TransportConstants.BYTES_TO_SEND_FLAG_NONE){
byte[] packet = receivedBundle.getByteArray(TransportConstants.BYTES_TO_SEND_EXTRA_NAME);
if(flags == TransportConstants.BYTES_TO_SEND_FLAG_LARGE_PACKET_START){
@@ -2203,12 +2229,18 @@ public class SdlRouterService extends Service{
if(messenger!=null){
if(deathNote == null){
deathNote = new DeathRecipient(){
+ final Object deathLock = new Object();
@Override
public void binderDied() {
- Log.w(TAG, "Binder died");
- removeAllSessionsForApp(RegisteredApp.this,true);
- removeAppFromMap(RegisteredApp.this);
- startClientPings();
+ synchronized(deathLock){
+ Log.w(TAG, "Binder died for app " + RegisteredApp.this.appId);
+ if(messenger!=null && messenger.getBinder()!=null){
+ messenger.getBinder().unlinkToDeath(this, 0);
+ }
+ removeAllSessionsForApp(RegisteredApp.this,true);
+ removeAppFromMap(RegisteredApp.this);
+ startClientPings();
+ }
}
};
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java
index f36dcb2c0..7daad4760 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/SdlRouterStatusProvider.java
@@ -23,6 +23,7 @@ public class SdlRouterStatusProvider {
ConnectedStatusCallback cb = null;
Messenger routerServiceMessenger = null;
private ComponentName routerService = null;
+ private int flags = 0;
final Messenger clientMessenger;
@@ -36,13 +37,14 @@ public class SdlRouterStatusProvider {
//Register with router service
Message msg = Message.obtain();
msg.what = TransportConstants.ROUTER_STATUS_CONNECTED_STATE_REQUEST;
+ msg.arg1 = flags;
msg.replyTo = clientMessenger;
try {
routerServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
if(cb!=null){
- cb.onConnectionStatusUpdate(false, context);
+ cb.onConnectionStatusUpdate(false, routerService, context);
}
}
}
@@ -64,11 +66,14 @@ public class SdlRouterStatusProvider {
this.clientMessenger = new Messenger(new ClientHandler(this));
}
-
+ public void setFlags(int flags){
+ this.flags = flags;
+ }
public void checkIsConnected(){
if(!bindToService()){
//We are unable to bind to service
- cb.onConnectionStatusUpdate(false, context);
+ cb.onConnectionStatusUpdate(false, routerService, context);
+ unBindFromService();
}
}
@@ -77,7 +82,7 @@ public class SdlRouterStatusProvider {
unBindFromService();
}
}
-
+
private boolean bindToService(){
if(isBound){
return true;
@@ -105,7 +110,7 @@ public class SdlRouterStatusProvider {
private void handleRouterStatusConnectedResponse(int connectedStatus){
if(cb!=null){
- cb.onConnectionStatusUpdate(connectedStatus == 1, context);
+ cb.onConnectionStatusUpdate(connectedStatus == 1, routerService,context);
}
unBindFromService();
routerServiceMessenger =null;
@@ -131,7 +136,7 @@ public class SdlRouterStatusProvider {
};
public interface ConnectedStatusCallback{
- public void onConnectionStatusUpdate(boolean connected, Context context);
+ public void onConnectionStatusUpdate(boolean connected, ComponentName service, Context context);
}
}
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/TransportBroker.java b/sdl_android_lib/src/com/smartdevicelink/transport/TransportBroker.java
index 493612ea3..aa5f35c3f 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/TransportBroker.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/TransportBroker.java
@@ -1,5 +1,6 @@
package com.smartdevicelink.transport;
+import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@@ -40,7 +41,7 @@ public class TransportBroker {
private TransportType queuedOnTransportConnect = null;
Messenger routerServiceMessenger = null;
- final Messenger clientMessenger = new Messenger(new ClientHandler());
+ final Messenger clientMessenger;
boolean isBound = false, registeredWithRouterService = false;
private String routerPackage = null, routerClassName = null;
@@ -65,7 +66,7 @@ public class TransportBroker {
}
public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "UN-Bound from service " + className.getClassName());
+ Log.d(TAG, "Unbound from service " + className.getClassName());
routerServiceMessenger = null;
registeredWithRouterService = false;
isBound = false;
@@ -125,12 +126,20 @@ public class TransportBroker {
/**
* Handler of incoming messages from service.
*/
- @SuppressLint("HandlerLeak")
- class ClientHandler extends Handler {
- ClassLoader loader = getClass().getClassLoader();
+ static class ClientHandler extends Handler {
+ ClassLoader loader;
+ WeakReference<TransportBroker> provider;
+
+ public ClientHandler(TransportBroker provider){
+ this.provider = new WeakReference<TransportBroker>(provider);
+ loader = getClass().getClassLoader();
+ }
@Override
public void handleMessage(Message msg) {
-
+ TransportBroker broker = provider.get();
+ if(broker == null){
+ Log.e(TAG, "Broker object null, unable to process message");
+ }
Bundle bundle = msg.getData();
if(bundle!=null){
@@ -143,8 +152,7 @@ public class TransportBroker {
if(bundle !=null
&& bundle.containsKey(TransportConstants.ENABLE_LEGACY_MODE_EXTRA)){
boolean enableLegacy = bundle.getBoolean(TransportConstants.ENABLE_LEGACY_MODE_EXTRA, false);
- Log.d(TAG, "Setting legacy mode: " +enableLegacy );
- enableLegacyMode(enableLegacy);
+ broker.enableLegacyMode(enableLegacy);
}
//Find out what message we have and what to do with it
@@ -153,13 +161,13 @@ public class TransportBroker {
switch(msg.arg1){
case TransportConstants.REGISTRATION_RESPONSE_SUCESS:
// yay! we have been registered. Now what?
- registeredWithRouterService = true;
+ broker.registeredWithRouterService = true;
if(bundle !=null){
if(bundle.containsKey(TransportConstants.HARDWARE_CONNECTED)){
if(bundle.containsKey(TransportConstants.CONNECTED_DEVICE_STRING_EXTRA_NAME)){
//Keep track if we actually get this
}
- onHardwareConnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_CONNECTED)));
+ broker.onHardwareConnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_CONNECTED)));
}
/*if(bundle.containsKey(TransportConstants.ROUTER_SERVICE_VERSION)){
//Keep track if we actually get this
@@ -168,14 +176,14 @@ public class TransportBroker {
break;
case TransportConstants.REGISTRATION_RESPONSE_DENIED_LEGACY_MODE_ENABLED:
Log.d(TAG, "Denied registration because router is in legacy mode" );
- registeredWithRouterService = false;
- enableLegacyMode(true);
+ broker.registeredWithRouterService = false;
+ broker.enableLegacyMode(true);
//We call this so we can start the process of legacy connection
//onHardwareDisconnected(TransportType.BLUETOOTH);
- onLegacyModeEnabled();
+ broker.onLegacyModeEnabled();
break;
default:
- registeredWithRouterService = false;
+ broker.registeredWithRouterService = false;
Log.w(TAG, "Registration denied from router service. Reason - " + msg.arg1);
break;
};
@@ -201,38 +209,36 @@ public class TransportBroker {
Parcelable packet = bundle.getParcelable(TransportConstants.FORMED_PACKET_EXTRA_NAME);
if(flags == TransportConstants.BYTES_TO_SEND_FLAG_NONE){
- if(packet!=null){ Log.i(TAG, "received packet to process "+ packet.toString());
- onPacketReceived(packet);
+ if(packet!=null){ //Log.i(TAG, "received packet to process "+ packet.toString());
+ broker.onPacketReceived(packet);
}else{
Log.w(TAG, "Received null packet from router service, not passing along");
}
}else if(flags == TransportConstants.BYTES_TO_SEND_FLAG_SDL_PACKET_INCLUDED){
- Log.i(TAG, "Starting a buffered split packet");
- bufferedPacket = (SdlPacket) packet;
- if(bufferedPayloadAssembler !=null){
- bufferedPayloadAssembler.close();
- bufferedPayloadAssembler = null;
+ broker.bufferedPacket = (SdlPacket) packet;
+ if(broker.bufferedPayloadAssembler !=null){
+ broker.bufferedPayloadAssembler.close();
+ broker.bufferedPayloadAssembler = null;
}
- bufferedPayloadAssembler = new ByteAraryMessageAssembler();
- bufferedPayloadAssembler.init();
+ broker.bufferedPayloadAssembler = new ByteAraryMessageAssembler();
+ broker.bufferedPayloadAssembler.init();
}
}else if(bundle.containsKey(TransportConstants.BYTES_TO_SEND_EXTRA_NAME)){
//This should contain the payload
- if(bufferedPayloadAssembler!=null){
+ if(broker.bufferedPayloadAssembler!=null){
byte[] chunk = bundle.getByteArray(TransportConstants.BYTES_TO_SEND_EXTRA_NAME);
- if(!bufferedPayloadAssembler.handleMessage(flags, chunk)){
+ if(!broker.bufferedPayloadAssembler.handleMessage(flags, chunk)){
//If there was a problem
Log.e(TAG, "Error handling bytes for split packet");
}
- if(bufferedPayloadAssembler.isFinished()){
- bufferedPacket.setPayload(bufferedPayloadAssembler.getBytes());
+ if(broker.bufferedPayloadAssembler.isFinished()){
+ broker.bufferedPacket.setPayload(broker.bufferedPayloadAssembler.getBytes());
- bufferedPayloadAssembler.close();
- bufferedPayloadAssembler = null;
- Log.i(TAG, "Split packet finished from router service = " + bufferedPacket.toString());
- onPacketReceived(bufferedPacket);
- bufferedPacket = null;
+ broker.bufferedPayloadAssembler.close();
+ broker.bufferedPayloadAssembler = null;
+ broker.onPacketReceived(broker.bufferedPacket);
+ broker.bufferedPacket = null;
}
}
//}
@@ -246,9 +252,9 @@ public class TransportBroker {
//We should shut down, so call
Log.d(TAG, "Hardware disconnected");
if(isLegacyModeEnabled()){
- onLegacyModeEnabled();
+ broker.onLegacyModeEnabled();
}else{
- onHardwareDisconnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_DISCONNECTED)));
+ broker.onHardwareDisconnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_DISCONNECTED)));
}
break;
}
@@ -257,7 +263,7 @@ public class TransportBroker {
if(bundle!=null && bundle.containsKey(TransportConstants.CONNECTED_DEVICE_STRING_EXTRA_NAME)){
//Keep track if we actually get this
}
- onHardwareConnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_CONNECTED)));
+ broker.onHardwareConnected(TransportType.valueOf(bundle.getString(TransportConstants.HARDWARE_CONNECTED)));
break;
}
break;
@@ -278,6 +284,7 @@ public class TransportBroker {
@SuppressLint("SimpleDateFormat")
public TransportBroker(Context context, String appId, ComponentName service){
synchronized(INIT_LOCK){
+ clientMessenger = new Messenger(new ClientHandler(this));
initRouterConnection();
//So the user should have set the AppId, lets define where the intents need to be sent
SimpleDateFormat s = new SimpleDateFormat("hhmmssss"); //So we have a time stamp of the event
@@ -301,7 +308,7 @@ public class TransportBroker {
* This beings the initial connection with the router service.
*/
public boolean start(){
- Log.d(TAG, "Starting up transport broker for " + whereToReply);
+ //Log.d(TAG, "Starting up transport broker for " + whereToReply);
synchronized(INIT_LOCK){
if(currentContext==null){
throw new IllegalStateException("This instance can't be started since it's local reference of context is null. Ensure when suppling a context to the TransportBroker that it is valid");
@@ -319,7 +326,6 @@ public class TransportBroker {
}
public void resetSession(){
- Log.d(TAG, "RESETING transport broker for " + whereToReply);
synchronized(INIT_LOCK){
unregisterWithRouterService();
routerServiceMessenger = null;
@@ -331,7 +337,7 @@ public class TransportBroker {
* This method will end our communication with the router service.
*/
public void stop(){
- Log.d(TAG, "STOPPING transport broker for " + whereToReply);
+ //Log.d(TAG, "STOPPING transport broker for " + whereToReply);
synchronized(INIT_LOCK){
unregisterWithRouterService();
unBindFromRouterService();
@@ -364,7 +370,7 @@ public class TransportBroker {
}
public void onHardwareDisconnected(TransportType type){
- synchronized(INIT_LOCK){Log.d(TAG, "onHardwareDisconnect");
+ synchronized(INIT_LOCK){
unBindFromRouterService();
routerServiceMessenger = null;
routerConnection = null;
@@ -397,7 +403,6 @@ public class TransportBroker {
* @return
*/
private boolean isRouterServiceRunning(Context context){
- Log.d(TAG,whereToReply + " checking if a bluetooth service is running");
if(context==null){
return false;
@@ -445,7 +450,7 @@ public class TransportBroker {
sendMessageToRouterService(message);
return true;
}else{ //Message is too big for IPC transaction
- Log.w(TAG, "Message too big for single IPC transaction. Breaking apart. Size - " + bytes.length);
+ //Log.w(TAG, "Message too big for single IPC transaction. Breaking apart. Size - " + bytes.length);
ByteArrayMessageSpliter splitter = new ByteArrayMessageSpliter(appId,TransportConstants.ROUTER_SEND_PACKET,bytes,packet.getPrioirtyCoefficient() );
while(splitter.isActive()){
sendMessageToRouterService(splitter.nextMessage());
diff --git a/sdl_android_lib/src/com/smartdevicelink/transport/TransportConstants.java b/sdl_android_lib/src/com/smartdevicelink/transport/TransportConstants.java
index ac9b9b6c6..612b5775a 100644
--- a/sdl_android_lib/src/com/smartdevicelink/transport/TransportConstants.java
+++ b/sdl_android_lib/src/com/smartdevicelink/transport/TransportConstants.java
@@ -11,10 +11,6 @@ package com.smartdevicelink.transport;
public class TransportConstants {
public static final String START_ROUTER_SERVICE_ACTION ="sdl.router.startservice";
- public static final String UNREGISTER_WITH_ROUTER_ACTION = "com.sdl.android.unregister";
- public static final String SEND_PACKET_ACTION = "com.sdl.android.sendpacket";
- public static final String SEND__GLOBAL_PACKET_ACTION = "com.sdl.android.sendglobalpacket";
-
public static final String BIND_LOCATION_PACKAGE_NAME_EXTRA = "BIND_LOCATION_PACKAGE_NAME_EXTRA";
public static final String BIND_LOCATION_CLASS_NAME_EXTRA = "BIND_LOCATION_CLASS_NAME_EXTRA";
@@ -38,10 +34,6 @@ public class TransportConstants {
public static final String APP_ID_EXTRA = "app.id";
public static final String SESSION_ID_EXTRA = "session.id";
- public static final String LOG_BASIC_DEBUG_BOOLEAN_EXTRA = "basicDebugBool";
- public static final String LOG_TRACE_BT_DEBUG_BOOLEAN_EXTRA = "btTraceBool";
-
-
public static final String ENABLE_LEGACY_MODE_EXTRA = "ENABLE_LEGACY_MODE_EXTRA";
public static final String HARDWARE_DISCONNECTED = "hardware.disconect";
@@ -198,6 +190,11 @@ public class TransportConstants {
public static final int ROUTER_STATUS_CONNECTED_STATE_REQUEST = 0x01;
public static final int ROUTER_STATUS_CONNECTED_STATE_RESPONSE = 0x02;
+ /**
+ * This flag when used to check router status will trigger the router service in sending out a ping that if it is connected to a device
+ */
+ public static final int ROUTER_STATUS_FLAG_TRIGGER_PING = 0x02;
+
diff --git a/sdl_android_lib/src/com/smartdevicelink/util/DebugTool.java b/sdl_android_lib/src/com/smartdevicelink/util/DebugTool.java
index 3b73b007c..716d96c59 100644
--- a/sdl_android_lib/src/com/smartdevicelink/util/DebugTool.java
+++ b/sdl_android_lib/src/com/smartdevicelink/util/DebugTool.java
@@ -1,10 +1,20 @@
package com.smartdevicelink.util;
+import java.util.Hashtable;
import java.util.Vector;
import android.util.Log;
import com.smartdevicelink.exception.SdlException;
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.protocol.BinaryFrameHeader;
+import com.smartdevicelink.protocol.ProtocolMessage;
+import com.smartdevicelink.protocol.SdlPacket;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.protocol.enums.MessageType;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.RPCMessage;
+import com.smartdevicelink.proxy.RPCStruct;
import com.smartdevicelink.proxy.Version;
import com.smartdevicelink.transport.SiphonServer;
@@ -267,4 +277,76 @@ public class DebugTool {
} // end-catch
}
}
+
+ /**
+ * Debug method to try to extract the RPC hash from the packet payload. Should only be used while debugging, not in production.
+ * Currently it will only handle single frame RPCs
+ * @param packet to inspect
+ * @return The Hashtable to be used to construct an RPC
+ */
+ public static Hashtable<String, Object> getRPCHash(SdlPacket packet){
+ if(packet == null ||
+ packet.getFrameType().getValue() != SdlPacket.FRAME_TYPE_SINGLE ||
+ packet.getServiceType()!=SdlPacket.SERVICE_TYPE_RPC){
+ Log.w("Debug", "Unable to get hash");
+ return null;
+ }
+ int version = packet.getVersion();
+
+ ProtocolMessage message = new ProtocolMessage();
+ SessionType serviceType = SessionType.valueOf((byte)packet.getServiceType());
+ if (serviceType == SessionType.RPC) {
+ message.setMessageType(MessageType.RPC);
+ } else if (serviceType == SessionType.BULK_DATA) {
+ message.setMessageType(MessageType.BULK);
+ } // end-if
+ message.setSessionType(serviceType);
+ message.setSessionID((byte)packet.getSessionId());
+ //If it is WiPro 2.0 it must have binary header
+ if (version > 1) {
+ BinaryFrameHeader binFrameHeader = BinaryFrameHeader.
+ parseBinaryHeader(packet.getPayload());
+ message.setVersion((byte) version);
+ message.setRPCType(binFrameHeader.getRPCType());
+ message.setFunctionID(binFrameHeader.getFunctionID());
+ message.setCorrID(binFrameHeader.getCorrID());
+ if (binFrameHeader.getJsonSize() > 0){
+ message.setData(binFrameHeader.getJsonData());
+ }
+ if (binFrameHeader.getBulkData() != null){
+ message.setBulkData(binFrameHeader.getBulkData());
+ }
+ } else {
+ message.setData(packet.getPayload());
+ }
+ Hashtable<String, Object> hash = new Hashtable<String, Object>();
+ if (packet.getVersion() > 1) {
+ Hashtable<String, Object> hashTemp = new Hashtable<String, Object>();
+
+ hashTemp.put(RPCMessage.KEY_CORRELATION_ID, message.getCorrID());
+ if (message.getJsonSize() > 0) {
+ final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData());
+ hashTemp.put(RPCMessage.KEY_PARAMETERS, mhash);
+ }
+
+ String functionName = FunctionID.getFunctionName(message.getFunctionID());
+ if (functionName != null) {
+ hashTemp.put(RPCMessage.KEY_FUNCTION_NAME, functionName);
+ } else {
+ return null;
+ }
+ if (message.getRPCType() == 0x00) {
+ hash.put(RPCMessage.KEY_REQUEST, hashTemp);
+ } else if (message.getRPCType() == 0x01) {
+ hash.put(RPCMessage.KEY_RESPONSE, hashTemp);
+ } else if (message.getRPCType() == 0x02) {
+ hash.put(RPCMessage.KEY_NOTIFICATION, hashTemp);
+ }
+ if (message.getBulkData() != null) hash.put(RPCStruct.KEY_BULK_DATA, message.getBulkData());
+ } else {
+ final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData());
+ hash = mhash;
+ }
+ return hash;
+ }
}