1
1
package com .smartdevicelink .transport ;
2
2
3
3
import java .util .Locale ;
4
+ import java .util .Vector ;
5
+ import java .util .concurrent .ConcurrentLinkedQueue ;
4
6
5
7
import android .app .ActivityManager ;
6
8
import android .app .ActivityManager .RunningServiceInfo ;
9
11
import android .content .ComponentName ;
10
12
import android .content .Context ;
11
13
import android .content .Intent ;
12
- import android .content .SharedPreferences ;
13
- import android .content .pm .PackageManager .NameNotFoundException ;
14
14
import android .util .Log ;
15
15
16
16
public abstract class SdlBroadcastReceiver extends BroadcastReceiver {
@@ -29,7 +29,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
29
29
public static final String TRANSPORT_GLOBAL_PREFS = "SdlTransportPrefs" ;
30
30
public static final String IS_TRANSPORT_CONNECTED = "isTransportConnected" ;
31
31
32
- public static ComponentName runningBluetoothServicePackage = null ;
32
+ public static Vector < ComponentName > runningBluetoothServicePackage = null ;
33
33
34
34
@ SuppressWarnings ("rawtypes" )
35
35
private static Class localRouterClass ;
@@ -72,15 +72,15 @@ public void onReceive(Context context, Intent intent) {
72
72
String packageName = intent .getStringExtra (TransportConstants .START_ROUTER_SERVICE_SDL_ENABLED_APP_PACKAGE );
73
73
ComponentName componentName = intent .getParcelableExtra (TransportConstants .START_ROUTER_SERVICE_SDL_ENABLED_CMP_NAME );
74
74
if (componentName !=null ){
75
- Log .v (TAG , "SDL enabled by router service from " + packageName + " compnent package " + componentName .getPackageName () + " - " + componentName .getClassName ());
75
+ // Log.v(TAG, "SDL enabled by router service from " + packageName + " compnent package " + componentName.getPackageName() + " - " + componentName.getClassName());
76
76
RouterServiceValidator vlad = new RouterServiceValidator (context ,componentName );
77
77
if (vlad .validate ()){
78
- Log .d (TAG , "Router service trusted!" );
78
+ // Log.d(TAG, "Router service trusted!");
79
79
queuedService = componentName ;
80
80
intent .setAction ("com.sdl.noaction" ); //Replace what's there so we do go into some unintended loop
81
81
onSdlEnabled (context , intent );
82
82
}else {
83
- Log .e (TAG , "RouterService was not trusted. Ignoring intent from : " + componentName .getClassName ());
83
+ Log .w (TAG , "RouterService was not trusted. Ignoring intent from : " + componentName .getClassName ());
84
84
}
85
85
86
86
}
@@ -93,7 +93,6 @@ public void onReceive(Context context, Intent intent) {
93
93
return ;
94
94
}else if (intent .getBooleanExtra (TransportConstants .PING_ROUTER_SERVICE_EXTRA , false )){
95
95
//We were told to wake up our router services
96
- Log .d (TAG , "Starting router service off ping" );
97
96
boolean altServiceWake = intent .getBooleanExtra (TransportConstants .BIND_REQUEST_TYPE_ALT_TRANSPORT , false );
98
97
didStart = wakeUpRouterService (context , false ,altServiceWake );
99
98
@@ -113,15 +112,13 @@ public void onReceive(Context context, Intent intent) {
113
112
return ;
114
113
}else if (state == BluetoothAdapter .STATE_TURNING_ON ){
115
114
//We started bluetooth, we should check for a new valid router list
116
- Log .d (TAG , "Attempting to get list of approved router services" );
117
115
RouterServiceValidator .createTrustedListRequest (context ,true );
118
116
}
119
117
}
120
118
121
119
if (localRouterClass !=null ){ //If there is a supplied router service lets run some logic regarding starting one
122
120
123
121
if (!didStart ){
124
- Log .d (TAG , "Waking up router service" );
125
122
didStart = wakeUpRouterService (context , true ,false );
126
123
}
127
124
@@ -138,10 +135,8 @@ public void onReceive(Context context, Intent intent) {
138
135
}
139
136
140
137
private boolean wakeUpRouterService (Context context , boolean ping , boolean altTransportWake ){
141
- Log .d (TAG , "Waking up router service" );
142
138
if (!isRouterServiceRunning (context , ping )){
143
139
//If there isn't a service running we should try to start one
144
- Log .i (TAG , "Attempting to start an instance of the Router Service" );
145
140
//The under class should have implemented this....
146
141
147
142
//So let's start up our service since no copy is running
@@ -152,18 +147,21 @@ private boolean wakeUpRouterService(Context context, boolean ping, boolean altTr
152
147
context .startService (serviceIntent );
153
148
return true ;
154
149
}else {
155
- Log .i (TAG , "An instance of the Router Service is already running" );
156
- if (altTransportWake ){
150
+ if (altTransportWake && runningBluetoothServicePackage !=null && runningBluetoothServicePackage .size ()>0 ){
157
151
Intent serviceIntent = new Intent ();
158
- serviceIntent .setComponent (runningBluetoothServicePackage );
159
152
serviceIntent .setAction (TransportConstants .BIND_REQUEST_TYPE_ALT_TRANSPORT );
160
- context .startService (serviceIntent );
153
+ //context.startService(serviceIntent);
154
+ for (ComponentName compName : runningBluetoothServicePackage ){
155
+ serviceIntent .setComponent (compName );
156
+ context .startService (serviceIntent );
157
+
158
+ }
161
159
return true ;
162
160
}
163
161
return false ;
164
162
}
165
163
}
166
-
164
+
167
165
/**
168
166
* Determines if an instance of the Router Service is currently running on the device.
169
167
* @param context A context to access Android system services through.
@@ -175,13 +173,18 @@ private static boolean isRouterServiceRunning(Context context, boolean pingServi
175
173
Log .e (TAG , "Can't look for router service, context supplied was null" );
176
174
return false ;
177
175
}
178
- Log .d (TAG , "Looking for Service: " + SDL_ROUTER_SERVICE_CLASS_NAME );
179
176
ActivityManager manager = (ActivityManager ) context .getSystemService (Context .ACTIVITY_SERVICE );
177
+ if (runningBluetoothServicePackage ==null ){
178
+ runningBluetoothServicePackage = new Vector <ComponentName >();
179
+ }else {
180
+ runningBluetoothServicePackage .clear ();
181
+ }
180
182
for (RunningServiceInfo service : manager .getRunningServices (Integer .MAX_VALUE )) {
181
183
//We will check to see if it contains this name, should be pretty specific
182
184
//Log.d(TAG, "Found Service: "+ service.service.getClassName());
183
185
if ((service .service .getClassName ()).toLowerCase (Locale .US ).contains (SDL_ROUTER_SERVICE_CLASS_NAME )) {
184
- runningBluetoothServicePackage = service .service ; //Store which instance is running
186
+
187
+ runningBluetoothServicePackage .add (service .service ); //Store which instance is running
185
188
if (pingService ){
186
189
Intent intent = new Intent ();
187
190
intent .setClassName (service .service .getPackageName (), service .service .getClassName ());
@@ -196,21 +199,64 @@ private static boolean isRouterServiceRunning(Context context, boolean pingServi
196
199
197
200
}
198
201
202
+ /**
203
+ * 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
204
+ * receive that ping and if the router service is trusted, the onSdlEnabled method will be called.
205
+ * @param context
206
+ */
207
+ public static void queryForConnectedService (Context context ){
208
+ //Leverage existing call. Include ping bit
209
+ requestTransportStatus (context ,null ,true );
210
+ }
199
211
/**
200
212
* If a Router Service is running, this method determines if that service is connected to a device over some form of transport.
201
213
* @param context A context to access Android system services through. If null is passed, this will always return false
202
214
* @param callback Use this callback to find out if the router service is connected or not.
203
215
*/
204
- public static void requestTransportStatus (Context context , SdlRouterStatusProvider .ConnectedStatusCallback callback ){
205
- Log .d (TAG , "Checking to see if router service is transport connected" );
216
+ public static void requestTransportStatus (Context context , final SdlRouterStatusProvider .ConnectedStatusCallback callback ){
217
+ requestTransportStatus (context ,callback ,false );
218
+ }
219
+
220
+ private static void requestTransportStatus (Context context , final SdlRouterStatusProvider .ConnectedStatusCallback callback , final boolean triggerRouterServicePing ){
206
221
if (context == null ){
207
222
if (callback !=null ){
208
- callback .onConnectionStatusUpdate (false , context );
223
+ callback .onConnectionStatusUpdate (false , null , context );
209
224
}
225
+ return ;
210
226
}
211
- if (isRouterServiceRunning (context ,false )){ //So there is a service up, let's see if it's connected
212
- SdlRouterStatusProvider provider = new SdlRouterStatusProvider (context ,runningBluetoothServicePackage ,callback );
213
- provider .checkIsConnected ();
227
+ if (isRouterServiceRunning (context ,false ) && !runningBluetoothServicePackage .isEmpty ()){ //So there is a service up, let's see if it's connected
228
+ final ConcurrentLinkedQueue <ComponentName > list = new ConcurrentLinkedQueue <ComponentName >(runningBluetoothServicePackage );
229
+ if (runningBluetoothServicePackage .size ()>0 ){ //TODO for testing do this for all cases
230
+ final SdlRouterStatusProvider .ConnectedStatusCallback sdlBrCallback = new SdlRouterStatusProvider .ConnectedStatusCallback () {
231
+
232
+ @ Override
233
+ public void onConnectionStatusUpdate (boolean connected , ComponentName service ,Context context ) {
234
+ if (!connected && !list .isEmpty ()){
235
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider (context ,list .poll (), this );
236
+ if (triggerRouterServicePing ){provider .setFlags (TransportConstants .ROUTER_STATUS_FLAG_TRIGGER_PING ); }
237
+ provider .checkIsConnected ();
238
+ }else {
239
+ Log .d (TAG , service .getPackageName () + " is connected = " + connected );
240
+ if (callback !=null ){
241
+ callback .onConnectionStatusUpdate (connected , service ,context );
242
+ }
243
+ list .clear ();
244
+ }
245
+
246
+ }
247
+ };
248
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider (context ,list .poll (),sdlBrCallback );
249
+ if (triggerRouterServicePing ){
250
+ provider .setFlags (TransportConstants .ROUTER_STATUS_FLAG_TRIGGER_PING );
251
+ }
252
+ provider .checkIsConnected ();
253
+ }else { //If only one service is running, just check that
254
+ SdlRouterStatusProvider provider = new SdlRouterStatusProvider (context ,runningBluetoothServicePackage .get (0 ),callback );
255
+ if (triggerRouterServicePing ){
256
+ provider .setFlags (TransportConstants .ROUTER_STATUS_FLAG_TRIGGER_PING );
257
+ }
258
+ provider .checkIsConnected ();
259
+ }
214
260
}else {
215
261
Log .w (TAG , "Router service isn't running, returning false." );
216
262
if (BluetoothAdapter .getDefaultAdapter ()!=null && BluetoothAdapter .getDefaultAdapter ().isEnabled ()){
@@ -220,10 +266,11 @@ public static void requestTransportStatus(Context context, SdlRouterStatusProvid
220
266
context .sendBroadcast (serviceIntent );
221
267
}
222
268
if (callback !=null ){
223
- callback .onConnectionStatusUpdate (false , context );
269
+ callback .onConnectionStatusUpdate (false , null , context );
224
270
}
225
271
}
226
272
}
273
+
227
274
228
275
229
276
public static ComponentName consumeQueuedRouterService (){
0 commit comments