Skip to content

Commit c367dd8

Browse files
Merge pull request #1399 from smartdevicelink/bugfix/refactor_lcm_updates
Refactor LCM Updates
2 parents b85d06a + 712c4a9 commit c367dd8

6 files changed

Lines changed: 294 additions & 392 deletions

File tree

android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public void run() {
216216
*/
217217
@SuppressLint("NewApi")
218218
@Override
219-
public void dispose() {
219+
public synchronized void dispose() {
220220
if (this.permissionManager != null) {
221221
this.permissionManager.dispose();
222222
}
Lines changed: 52 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019 Livio, Inc.
2+
* Copyright (c) 2019-2020 Livio, Inc.
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -54,38 +54,29 @@
5454
import com.smartdevicelink.transport.enums.TransportType;
5555
import com.smartdevicelink.util.DebugTool;
5656

57+
import java.lang.ref.WeakReference;
5758
import java.util.ArrayList;
5859
import java.util.Collections;
59-
import java.util.concurrent.Callable;
60-
import java.util.concurrent.Executors;
61-
import java.util.concurrent.FutureTask;
62-
import java.util.concurrent.ScheduledExecutorService;
6360

6461
/**
6562
* The lifecycle manager creates a central point for all SDL session logic to converge. It should only be used by
6663
* the library itself. Usage outside the library is not permitted and will not be protected for in the future.
6764
*
68-
* @author Bilal Alsharifi.
6965
*/
7066
@RestrictTo(RestrictTo.Scope.LIBRARY)
7167
public class LifecycleManager extends BaseLifecycleManager {
72-
private static final int RESPONSE_WAIT_TIME = 2000;
73-
private ISdlServiceListener navServiceListener;
74-
private boolean navServiceStartResponseReceived = false;
75-
private boolean navServiceStartResponse = false;
76-
private boolean navServiceEndResponseReceived = false;
77-
private boolean navServiceEndResponse = false;
78-
private boolean pcmServiceEndResponseReceived = false;
79-
private boolean pcmServiceEndResponse = false;
80-
private Context context;
68+
private ISdlServiceListener videoServiceListener;
69+
private boolean videoServiceStartResponseReceived = false;
70+
private boolean videoServiceStartResponse = false;
71+
private WeakReference<Context> contextWeakReference;
8172

8273
public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) {
8374
super(appConfig, config, listener);
8475
}
8576

8677
@Override
87-
void initializeProxy() {
88-
super.initializeProxy();
78+
void initialize() {
79+
super.initialize();
8980

9081
//Handle legacy USB connections
9182
if (_transportConfig != null && TransportType.USB.equals(_transportConfig.getTransportType())) {
@@ -113,9 +104,9 @@ void initializeProxy() {
113104
}
114105

115106
@Override
116-
void cycleProxy(SdlDisconnectedReason disconnectedReason) {
117-
cleanProxy();
118-
initializeProxy();
107+
void cycle(SdlDisconnectedReason disconnectedReason) {
108+
clean();
109+
initialize();
119110
if (!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason) && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(disconnectedReason)) {
120111
//We don't want to alert higher if we are just cycling for legacy bluetooth
121112
onClose("Sdl Proxy Cycled", new SdlException("Sdl Proxy Cycled", SdlExceptionCause.SDL_PROXY_CYCLED), disconnectedReason);
@@ -131,14 +122,19 @@ void cycleProxy(SdlDisconnectedReason disconnectedReason) {
131122

132123
@RestrictTo(RestrictTo.Scope.LIBRARY)
133124
public void setContext(Context context) {
134-
this.context = context;
125+
this.contextWeakReference = new WeakReference<>(context);
135126
}
136127

137128
@Override
138129
void setSdlSecurityStaticVars() {
139130
super.setSdlSecurityStaticVars();
140131

132+
Context context = null;
141133
Service service = null;
134+
135+
if(this.contextWeakReference != null){
136+
context = contextWeakReference.get();
137+
}
142138
if (context != null && context instanceof Service) {
143139
service = (Service) context;
144140
}
@@ -147,11 +143,11 @@ void setSdlSecurityStaticVars() {
147143
}
148144

149145
@Override
150-
void onProtocolSessionStarted(SessionType sessionType) {
151-
super.onProtocolSessionStarted(sessionType);
146+
void onServiceStarted(SessionType sessionType) {
147+
super.onServiceStarted(sessionType);
152148
if (sessionType.eq(SessionType.NAV)) {
153-
navServiceStartResponseReceived = true;
154-
navServiceStartResponse = true;
149+
videoServiceStartResponseReceived = true;
150+
videoServiceStartResponse = true;
155151
}
156152
}
157153

@@ -161,42 +157,18 @@ void onTransportDisconnected(String info, boolean availablePrimary, BaseTranspor
161157
if (availablePrimary) {
162158
_transportConfig = transportConfig;
163159
Log.d(TAG, "notifying RPC session ended, but potential primary transport available");
164-
cycleProxy(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST);
160+
cycle(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST);
165161
} else {
166162
onClose(info, null, null);
167163
}
168164
}
169165

170166
@Override
171-
void onProtocolSessionStartedNACKed(SessionType sessionType) {
172-
super.onProtocolSessionStartedNACKed(sessionType);
173-
if (sessionType.eq(SessionType.NAV)) {
174-
navServiceStartResponseReceived = true;
175-
navServiceStartResponse = false;
176-
}
177-
}
178-
179-
@Override
180-
void onProtocolSessionEnded(SessionType sessionType) {
181-
super.onProtocolSessionEnded(sessionType);
167+
void onStartServiceNACKed(SessionType sessionType) {
168+
super.onStartServiceNACKed(sessionType);
182169
if (sessionType.eq(SessionType.NAV)) {
183-
navServiceEndResponseReceived = true;
184-
navServiceEndResponse = true;
185-
} else if (sessionType.eq(SessionType.PCM)) {
186-
pcmServiceEndResponseReceived = true;
187-
pcmServiceEndResponse = true;
188-
}
189-
}
190-
191-
@Override
192-
void onProtocolSessionEndedNACKed(SessionType sessionType) {
193-
super.onProtocolSessionEndedNACKed(sessionType);
194-
if (sessionType.eq(SessionType.NAV)) {
195-
navServiceEndResponseReceived = true;
196-
navServiceEndResponse = false;
197-
} else if (sessionType.eq(SessionType.PCM)) {
198-
pcmServiceEndResponseReceived = true;
199-
pcmServiceEndResponse = false;
170+
videoServiceStartResponseReceived = true;
171+
videoServiceStartResponse = false;
200172
}
201173
}
202174

@@ -233,72 +205,60 @@ void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters)
233205
* mode (i.e. without any negotiation) then an instance of VideoStreamingParams is
234206
* returned. If the service was not opened then null is returned.
235207
*/
236-
private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
208+
private void tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
237209
if (session == null) {
238210
DebugTool.logWarning("SdlSession is not created yet.");
239-
return null;
211+
return;
240212
}
241213
if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) {
242214
DebugTool.logWarning("Module doesn't support video streaming.");
243-
return null;
215+
return;
244216
}
245217
if (parameters == null) {
246218
DebugTool.logWarning("Video parameters were not supplied.");
247-
return null;
219+
return;
248220
}
249221

250-
if (!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before
251-
|| (navServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one
222+
223+
if (!videoServiceStartResponseReceived || !videoServiceStartResponse //If we haven't started the service before
224+
|| (videoServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one
252225
session.setDesiredVideoParams(parameters);
253226

254-
navServiceStartResponseReceived = false;
255-
navServiceStartResponse = false;
227+
videoServiceStartResponseReceived = false;
228+
videoServiceStartResponse = false;
256229

230+
addVideoServiceListener();
257231
session.startService(SessionType.NAV, session.getSessionId(), isEncrypted);
258-
addNavListener();
259-
FutureTask<Void> fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME));
260-
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
261-
scheduler.execute(fTask);
262-
263-
//noinspection StatementWithEmptyBody
264-
while (!navServiceStartResponseReceived && !fTask.isDone()) ;
265-
scheduler.shutdown();
266-
}
267232

268-
if (navServiceStartResponse) {
269-
if (getProtocolVersion() != null && getProtocolVersion().getMajor() < 5) { //Versions 1-4 do not support streaming parameter negotiations
270-
session.setAcceptedVideoParams(parameters);
271-
}
272-
return session.getAcceptedVideoParams();
273233
}
274-
275-
return null;
276234
}
277235

278-
private void addNavListener() {
236+
private void addVideoServiceListener() {
279237
// videos may be started and stopped. Only add this once
280-
if (navServiceListener == null) {
238+
if (videoServiceListener == null) {
281239

282-
navServiceListener = new ISdlServiceListener() {
240+
videoServiceListener = new ISdlServiceListener() {
283241
@Override
284242
public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) {
243+
videoServiceStartResponseReceived = true;
244+
videoServiceStartResponse = true;
285245
}
286246

287247
@Override
288248
public void onServiceEnded(SdlSession session, SessionType type) {
289249
// reset nav flags so nav can start upon the next transport connection
290-
navServiceStartResponseReceived = false;
291-
navServiceStartResponse = false;
250+
videoServiceStartResponseReceived = false;
251+
videoServiceStartResponse = false;
292252
}
293253

294254
@Override
295255
public void onServiceError(SdlSession session, SessionType type, String reason) {
296256
// if there is an error reset the flags so that there is a chance to restart streaming
297-
navServiceStartResponseReceived = false;
298-
navServiceStartResponse = false;
257+
videoServiceStartResponseReceived = false;
258+
videoServiceStartResponse = false;
299259
}
300260
};
301-
session.addServiceListener(SessionType.NAV, navServiceListener);
261+
session.addServiceListener(SessionType.NAV, videoServiceListener);
302262
}
303263
}
304264

@@ -308,29 +268,17 @@ public void onServiceError(SdlSession session, SessionType type, String reason)
308268
* @return true if the video service is closed successfully, return false otherwise
309269
*/
310270
@Override
311-
boolean endVideoStream() {
271+
void endVideoStream() {
312272
if (session == null) {
313273
DebugTool.logWarning("SdlSession is not created yet.");
314-
return false;
274+
return;
315275
}
316276
if (!session.getIsConnected()) {
317277
DebugTool.logWarning("Connection is not available.");
318-
return false;
278+
return;
319279
}
320280

321-
navServiceEndResponseReceived = false;
322-
navServiceEndResponse = false;
323281
session.stopVideoStream();
324-
325-
FutureTask<Void> fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME));
326-
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
327-
scheduler.execute(fTask);
328-
329-
//noinspection StatementWithEmptyBody
330-
while (!navServiceEndResponseReceived && !fTask.isDone()) ;
331-
scheduler.shutdown();
332-
333-
return navServiceEndResponse;
334282
}
335283

336284
@Override
@@ -352,46 +300,16 @@ void startAudioService(boolean isEncrypted) {
352300
* @return true if the audio service is closed successfully, return false otherwise
353301
*/
354302
@Override
355-
boolean endAudioStream() {
303+
void endAudioStream() {
356304
if (session == null) {
357305
DebugTool.logWarning("SdlSession is not created yet.");
358-
return false;
306+
return;
359307
}
360308
if (!session.getIsConnected()) {
361309
DebugTool.logWarning("Connection is not available.");
362-
return false;
310+
return;
363311
}
364312

365-
pcmServiceEndResponseReceived = false;
366-
pcmServiceEndResponse = false;
367313
session.stopAudioStream();
368-
369-
FutureTask<Void> fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME));
370-
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
371-
scheduler.execute(fTask);
372-
373-
//noinspection StatementWithEmptyBody
374-
while (!pcmServiceEndResponseReceived && !fTask.isDone()) ;
375-
scheduler.shutdown();
376-
377-
return pcmServiceEndResponse;
378-
}
379-
380-
private class CallableMethod implements Callable<Void> {
381-
private final long waitTime;
382-
383-
public CallableMethod(int timeInMillis) {
384-
this.waitTime = timeInMillis;
385-
}
386-
387-
@Override
388-
public Void call() {
389-
try {
390-
Thread.sleep(waitTime);
391-
} catch (InterruptedException e) {
392-
e.printStackTrace();
393-
}
394-
return null;
395-
}
396314
}
397315
}

0 commit comments

Comments
 (0)