diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index 21758d47e0..8324e6344d 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -76,12 +76,14 @@ public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, Lifecyc void initialize() { super.initialize(); - if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.MULTIPLEX)) { - this.session = new SdlSession(sdlSessionListener, (MultiplexTransportConfig) _transportConfig); - } else if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.TCP)) { - this.session = new SdlSession(sdlSessionListener, (TCPTransportConfig) _transportConfig); - } else { - DebugTool.logError(TAG, "Unable to create session for transport type"); + synchronized (SESSION_LOCK) { + if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.MULTIPLEX)) { + this.session = new SdlSession(sdlSessionListener, (MultiplexTransportConfig) _transportConfig); + } else if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.TCP)) { + this.session = new SdlSession(sdlSessionListener, (TCPTransportConfig) _transportConfig); + } else { + DebugTool.logError(TAG, "Unable to create session for transport type"); + } } } @@ -93,11 +95,13 @@ void cycle(SdlDisconnectedReason disconnectedReason) { //We don't want to alert higher if we are just cycling for legacy bluetooth onClose("Sdl Proxy Cycled", new SdlException("Sdl Proxy Cycled", SdlExceptionCause.SDL_PROXY_CYCLED), disconnectedReason); } - if (session != null) { - try { - session.startSession(); - } catch (SdlException e) { - e.printStackTrace(); + synchronized (SESSION_LOCK) { + if (session != null) { + try { + session.startSession(); + } catch (SdlException e) { + e.printStackTrace(); + } } } } @@ -163,16 +167,18 @@ void onTransportDisconnected(String info, boolean availablePrimary, BaseTranspor */ @Override void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters, boolean afterPendingRestart) { - if (session == null) { - DebugTool.logWarning(TAG, "SdlSession is not created yet."); - return; - } - if (!session.getIsConnected()) { - DebugTool.logWarning(TAG, "Connection is not available."); - return; - } + synchronized (SESSION_LOCK) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } - session.setDesiredVideoParams(parameters); + session.setDesiredVideoParams(parameters); + } tryStartVideoStream(isEncrypted, parameters, afterPendingRestart); } @@ -185,9 +191,11 @@ void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters, * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. */ private void tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters, boolean afterPendingRestart) { - if (session == null) { - DebugTool.logWarning(TAG, "SdlSession is not created yet."); - return; + synchronized (SESSION_LOCK) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } } if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) { DebugTool.logWarning(TAG, "Module doesn't support video streaming."); @@ -198,17 +206,20 @@ private void tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters p return; } + synchronized (SESSION_LOCK) { + if (afterPendingRestart || !videoServiceStartResponseReceived || !videoServiceStartResponse //If we haven't started the service before + || (videoServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one + if (session != null) { + session.setDesiredVideoParams(parameters); + } + videoServiceStartResponseReceived = false; + videoServiceStartResponse = false; - if (afterPendingRestart || !videoServiceStartResponseReceived || !videoServiceStartResponse //If we haven't started the service before - || (videoServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one - session.setDesiredVideoParams(parameters); - - videoServiceStartResponseReceived = false; - videoServiceStartResponse = false; - - addVideoServiceListener(); - session.startService(SessionType.NAV, isEncrypted); - + addVideoServiceListener(); + if (session != null) { + session.startService(SessionType.NAV, isEncrypted); + } + } } } @@ -237,20 +248,27 @@ public void onServiceError(SdlSession session, SessionType type, String reason) videoServiceStartResponse = false; } }; - session.addServiceListener(SessionType.NAV, videoServiceListener); + + synchronized (SESSION_LOCK) { + if (session != null) { + session.addServiceListener(SessionType.NAV, videoServiceListener); + } + } } } @Override void startAudioService(boolean isEncrypted) { - if (session == null) { - DebugTool.logWarning(TAG, "SdlSession is not created yet."); - return; - } - if (!session.getIsConnected()) { - DebugTool.logWarning(TAG, "Connection is not available."); - return; + synchronized (SESSION_LOCK) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } + session.startService(SessionType.PCM, isEncrypted); } - session.startService(SessionType.PCM, isEncrypted); } } diff --git a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java index 0847d5d7c5..bf9865ca2d 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -116,6 +116,8 @@ abstract class BaseLifecycleManager { ON_UPDATE_LISTENER_LOCK = new Object(), ON_REQUEST_LISTENER_LOCK = new Object(), ON_NOTIFICATION_LISTENER_LOCK = new Object(); + protected static final Object SESSION_LOCK = new Object(); + SdlSession session; final AppConfig appConfig; @@ -151,7 +153,11 @@ abstract class BaseLifecycleManager { public void start() { try { - session.startSession(); + synchronized (SESSION_LOCK) { + if (session != null) { + session.startSession(); + } + } } catch (SdlException e) { DebugTool.logError(TAG, "Error attempting to start session", e); } @@ -161,15 +167,19 @@ public void start() { * Start a secured RPC service */ public void startRPCEncryption() { - if (session != null) { - session.startService(SessionType.RPC, true); + synchronized (SESSION_LOCK) { + if (session != null) { + session.startService(SessionType.RPC, true); + } } } public synchronized void stop() { - if (session != null) { - session.close(); - session = null; + synchronized (SESSION_LOCK) { + if (session != null) { + session.close(); + session = null; + } } if (taskmaster != null) { taskmaster.shutdown(); @@ -194,8 +204,10 @@ Taskmaster getTaskmaster() { } Version getProtocolVersion() { - if (session != null && session.getProtocolVersion() != null) { - return session.getProtocolVersion(); + synchronized (SESSION_LOCK) { + if (session != null && session.getProtocolVersion() != null) { + return session.getProtocolVersion(); + } } return new Version(1, 0, 0); } @@ -301,10 +313,12 @@ public SystemCapabilityManager getSystemCapabilityManager(SdlManager sdlManager) } private boolean isConnected() { - if (session != null) { - return session.getIsConnected(); - } else { - return false; + synchronized (SESSION_LOCK) { + if (session != null) { + return session.getIsConnected(); + } else { + return false; + } } } @@ -399,7 +413,14 @@ public void onReceived(RPCMessage message) { VehicleType vehicleType = raiResponse.getVehicleType(); String systemSoftwareVersion = raiResponse.getSystemSoftwareVersion(); if (vehicleType != null || systemSoftwareVersion != null) { - saveVehicleType(session.getActiveTransports(), vehicleType); + + List activeTransports = null; + synchronized (SESSION_LOCK) { + if (session != null) { + activeTransports = session.getActiveTransports(); + } + } + saveVehicleType(activeTransports, vehicleType); SystemInfo systemInfo = new SystemInfo(vehicleType, systemSoftwareVersion, null); boolean validSystemInfo = lifecycleListener.onSystemInfoReceived(systemInfo); if (!validSystemInfo) { @@ -799,8 +820,10 @@ private void sendRPCMessagePrivate(RPCMessage message, boolean isInternalMessage final ProtocolMessage pm = new ProtocolMessage(); pm.setData(msgBytes); - if (session != null) { - pm.setSessionID((byte) session.getSessionId()); + synchronized (SESSION_LOCK) { + if (session != null) { + pm.setSessionID((byte) session.getSessionId()); + } } pm.setMessageType(MessageType.RPC); @@ -868,7 +891,11 @@ private void sendRPCMessagePrivate(RPCMessage message, boolean isInternalMessage pm.setPriorityCoefficient(1); } - session.sendMessage(pm); + synchronized (SESSION_LOCK) { + if (session != null) { + session.sendMessage(pm); + } + } } catch (OutOfMemoryError e) { DebugTool.logError(TAG, "Error attempting to send RPC message.", e); @@ -940,7 +967,11 @@ public void onSessionStarted(int sessionID, Version version, SystemInfo systemIn DebugTool.logInfo(TAG, "on protocol session started"); if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(version) == 1) { DebugTool.logWarning(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion())); - session.endService(SessionType.RPC); + synchronized (SESSION_LOCK) { + if (session != null) { + session.endService(SessionType.RPC); + } + } clean(); onClose("Protocol version not supported: " + version, null, SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED); return; @@ -948,14 +979,24 @@ public void onSessionStarted(int sessionID, Version version, SystemInfo systemIn if (systemInfo != null && lifecycleListener != null) { didCheckSystemInfo = true; - saveVehicleType(session.getActiveTransports(), systemInfo.getVehicleType()); + List activeTransports = null; + synchronized (SESSION_LOCK) { + if (session != null) { + activeTransports = session.getActiveTransports(); + } + } + saveVehicleType(activeTransports, systemInfo.getVehicleType()); boolean validSystemInfo = lifecycleListener.onSystemInfoReceived(systemInfo); if (!validSystemInfo) { DebugTool.logWarning(TAG, "Disconnecting from head unit, the system info was not accepted."); - session.endService(SessionType.RPC); - clean(); - onClose("System not supported", null, SdlDisconnectedReason.DEFAULT); - return; + synchronized (SESSION_LOCK) { + if (session != null) { + session.endService(SessionType.RPC); + } + clean(); + onClose("System not supported", null, SdlDisconnectedReason.DEFAULT); + return; + } } //If the vehicle is acceptable, init security lib setSecurityLibraryIfAvailable(systemInfo.getVehicleType()); @@ -1024,8 +1065,10 @@ public void stop() { @Override public boolean isConnected() { synchronized (BaseLifecycleManager.this) { - if (BaseLifecycleManager.this.session != null) { - return BaseLifecycleManager.this.session.getIsConnected(); + synchronized (SESSION_LOCK) { + if (BaseLifecycleManager.this.session != null) { + return BaseLifecycleManager.this.session.getIsConnected(); + } } } return false; @@ -1034,8 +1077,10 @@ public boolean isConnected() { @Override public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { synchronized (BaseLifecycleManager.this) { - if (BaseLifecycleManager.this.session != null) { - BaseLifecycleManager.this.session.addServiceListener(serviceType, sdlServiceListener); + synchronized (SESSION_LOCK) { + if (BaseLifecycleManager.this.session != null) { + BaseLifecycleManager.this.session.addServiceListener(serviceType, sdlServiceListener); + } } } } @@ -1043,8 +1088,10 @@ public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlS @Override public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { synchronized (BaseLifecycleManager.this) { - if (BaseLifecycleManager.this.session != null) { - BaseLifecycleManager.this.session.removeServiceListener(serviceType, sdlServiceListener); + synchronized (SESSION_LOCK) { + if (BaseLifecycleManager.this.session != null) { + BaseLifecycleManager.this.session.removeServiceListener(serviceType, sdlServiceListener); + } } } } @@ -1114,8 +1161,10 @@ public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { @Override public boolean isTransportForServiceAvailable(SessionType serviceType) { synchronized (BaseLifecycleManager.this) { - if (BaseLifecycleManager.this.session != null) { - return BaseLifecycleManager.this.session.isTransportForServiceAvailable(serviceType); + synchronized (SESSION_LOCK) { + if (BaseLifecycleManager.this.session != null) { + return BaseLifecycleManager.this.session.isTransportForServiceAvailable(serviceType); + } } } return false; @@ -1144,8 +1193,10 @@ public Version getProtocolVersion() { @Override public long getMtu(SessionType serviceType) { synchronized (BaseLifecycleManager.this) { - if (BaseLifecycleManager.this.session != null) { - return BaseLifecycleManager.this.session.getMtu(serviceType); + synchronized (SESSION_LOCK) { + if (BaseLifecycleManager.this.session != null) { + return BaseLifecycleManager.this.session.getMtu(serviceType); + } } } return SdlProtocolBase.V1_V2_MTU_SIZE; @@ -1246,8 +1297,10 @@ void clean() { if (rpcRequestListeners != null) { rpcRequestListeners.clear(); } - if (session != null && session.getIsConnected()) { - session.close(); + synchronized (SESSION_LOCK) { + if (session != null && session.getIsConnected()) { + session.close(); + } } if (encryptionLifecycleManager != null) { encryptionLifecycleManager.dispose(); @@ -1302,9 +1355,11 @@ private void setSecurityLibraryIfAvailable(VehicleType vehicleType) { if ((sec != null) && (sec.getMakeList() != null)) { if (sec.getMakeList().contains(make)) { sec.setAppId(appConfig.getAppID()); - if (session != null) { - session.setSdlSecurity(sec); - sec.handleSdlSession(session); + synchronized (SESSION_LOCK) { + if (session != null) { + session.setSdlSecurity(sec); + sec.handleSdlSession(session); + } } return; }