diff options
5 files changed, 76 insertions, 41 deletions
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java index 9fcb65b12..6dc3ce4aa 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -237,6 +237,11 @@ public class SdlManager extends BaseSdlManager { @SuppressLint("NewApi") @Override public synchronized void dispose() { + int state = getState(); + if (state == BaseSubManager.SHUTDOWN || state == BaseSubManager.ERROR) { + DebugTool.logInfo(TAG, "SdlManager already disposed"); + return; + } if (this.permissionManager != null) { this.permissionManager.dispose(); } @@ -414,7 +419,7 @@ public class SdlManager extends BaseSdlManager { @Override public void stop() { - lifecycleManager.getInternalInterface(SdlManager.this).start(); + lifecycleManager.getInternalInterface(SdlManager.this).stop(); } @Override 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 8324e6344..bfe73c19f 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 @@ -32,6 +32,8 @@ package com.smartdevicelink.managers.lifecycle; +import static com.smartdevicelink.managers.BaseSubManager.SETTING_UP; + import android.content.Context; import androidx.annotation.RestrictTo; @@ -89,12 +91,13 @@ public class LifecycleManager extends BaseLifecycleManager { @Override void cycle(SdlDisconnectedReason disconnectedReason) { - clean(); - initialize(); + clean(true); if (!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason) && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(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); } + transitionToState(SETTING_UP); + initialize(); synchronized (SESSION_LOCK) { if (session != null) { try { 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 bf9865ca2..f1b20237b 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -32,6 +32,12 @@ package com.smartdevicelink.managers.lifecycle; +import static com.smartdevicelink.managers.BaseSubManager.SETTING_UP; +import static com.smartdevicelink.managers.BaseSubManager.READY; +import static com.smartdevicelink.managers.BaseSubManager.LIMITED; +import static com.smartdevicelink.managers.BaseSubManager.SHUTDOWN; +import static com.smartdevicelink.managers.BaseSubManager.ERROR; + import androidx.annotation.NonNull; import androidx.annotation.RestrictTo; @@ -117,8 +123,9 @@ abstract class BaseLifecycleManager { ON_REQUEST_LISTENER_LOCK = new Object(), ON_NOTIFICATION_LISTENER_LOCK = new Object(); protected static final Object SESSION_LOCK = new Object(); + private final Object STATE_LOCK = new Object(); - + private int state; SdlSession session; final AppConfig appConfig; Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; @@ -143,6 +150,7 @@ abstract class BaseLifecycleManager { DisplayCapabilities initialMediaCapabilities; BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + transitionToState(SETTING_UP); this.appConfig = appConfig; this._transportConfig = config; this.lifecycleListener = listener; @@ -175,15 +183,20 @@ abstract class BaseLifecycleManager { } public synchronized void stop() { - synchronized (SESSION_LOCK) { - if (session != null) { - session.close(); - session = null; - } + DebugTool.logInfo(TAG, "LifecycleManager stop requested"); + clean(true); + transitionToState(SHUTDOWN); + } + + protected void transitionToState(int state) { + synchronized (STATE_LOCK) { + this.state = state; } - if (taskmaster != null) { - taskmaster.shutdown(); - taskmaster = null; + } + + public int getState() { + synchronized (STATE_LOCK) { + return state; } } @@ -345,6 +358,7 @@ abstract class BaseLifecycleManager { void onClose(String info, Exception e, SdlDisconnectedReason reason) { DebugTool.logInfo(TAG, "onClose"); + transitionToState(SHUTDOWN); if (lifecycleListener != null) { lifecycleListener.onClosed((LifecycleManager) this, info, e, reason); } @@ -401,10 +415,7 @@ abstract class BaseLifecycleManager { } if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1) { DebugTool.logWarning(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion)); - UnregisterAppInterface msg = new UnregisterAppInterface(); - msg.setCorrelationID(UNREGISTER_APP_INTERFACE_CORRELATION_ID); - sendRPCMessagePrivate(msg, true); - clean(); + clean(true); onClose("RPC spec version not supported: " + rpcSpecVersion.toString(), null, SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED); return; } @@ -425,10 +436,7 @@ abstract class BaseLifecycleManager { boolean validSystemInfo = lifecycleListener.onSystemInfoReceived(systemInfo); if (!validSystemInfo) { DebugTool.logWarning(TAG, "Disconnecting from head unit, the system info was not accepted."); - UnregisterAppInterface msg = new UnregisterAppInterface(); - msg.setCorrelationID(UNREGISTER_APP_INTERFACE_CORRELATION_ID); - sendRPCMessagePrivate(msg, true); - clean(); + clean(true); onClose("System not supported", null, SdlDisconnectedReason.DEFAULT); return; } @@ -446,6 +454,7 @@ abstract class BaseLifecycleManager { DebugTool.logInfo(TAG, "on hmi status"); boolean shouldInit = currentHMIStatus == null; currentHMIStatus = (OnHMIStatus) message; + transitionToState(READY); if (lifecycleListener != null && shouldInit) { lifecycleListener.onConnected((LifecycleManager) BaseLifecycleManager.this); } @@ -515,7 +524,7 @@ abstract class BaseLifecycleManager { if (!onAppInterfaceUnregistered.getReason().equals(AppInterfaceUnregisteredReason.LANGUAGE_CHANGE)) { DebugTool.logInfo(TAG, "on app interface unregistered"); - clean(); + clean(false); onClose("OnAppInterfaceUnregistered received from head unit", null, SdlDisconnectedReason.APP_INTERFACE_UNREG); } else { DebugTool.logInfo(TAG, "re-registering for language change"); @@ -523,9 +532,11 @@ abstract class BaseLifecycleManager { } break; case UNREGISTER_APP_INTERFACE: - DebugTool.logInfo(TAG, "unregister app interface"); - clean(); - onClose("UnregisterAppInterface response received from head unit", null, SdlDisconnectedReason.APP_INTERFACE_UNREG); + DebugTool.logInfo(TAG, "Unregister app interface response received"); + //Since only the library sends the UnregisterAppInterface requests, we know + //that the correct logic flows already happen based on where the call to send + //the request happens. There is also a SYNC4 bug that holds onto the response + //until the app reconnects within the same transport session. break; } } @@ -967,12 +978,7 @@ abstract class BaseLifecycleManager { 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())); - synchronized (SESSION_LOCK) { - if (session != null) { - session.endService(SessionType.RPC); - } - } - clean(); + clean(false); onClose("Protocol version not supported: " + version, null, SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED); return; } @@ -989,14 +995,10 @@ abstract class BaseLifecycleManager { boolean validSystemInfo = lifecycleListener.onSystemInfoReceived(systemInfo); if (!validSystemInfo) { DebugTool.logWarning(TAG, "Disconnecting from head unit, the system info was not accepted."); - synchronized (SESSION_LOCK) { - if (session != null) { - session.endService(SessionType.RPC); - } - clean(); - onClose("System not supported", null, SdlDisconnectedReason.DEFAULT); - return; - } + clean(false); + onClose("System not supported", null, SdlDisconnectedReason.DEFAULT); + return; + } //If the vehicle is acceptable, init security lib setSecurityLibraryIfAvailable(systemInfo.getVehicleType()); @@ -1280,7 +1282,20 @@ abstract class BaseLifecycleManager { return null; } - void clean() { + void clean(boolean sendUnregisterAppInterface) { + int state = getState(); + if (state == SHUTDOWN || state == ERROR) { + DebugTool.logInfo(TAG, "No need to clean, LCM is already cleaned: " + state); + return; + } + + if (sendUnregisterAppInterface) { + DebugTool.logInfo(TAG, "Requesting to unregister from device"); + UnregisterAppInterface uai = new UnregisterAppInterface(); + uai.setCorrelationID(UNREGISTER_APP_INTERFACE_CORRELATION_ID); + sendRPCMessagePrivate(uai, true); + } + firstTimeFull = true; currentHMIStatus = null; lastDisplayLayoutRequestTemplate = null; @@ -1300,6 +1315,7 @@ abstract class BaseLifecycleManager { synchronized (SESSION_LOCK) { if (session != null && session.getIsConnected()) { session.close(); + session = null; } } if (encryptionLifecycleManager != null) { @@ -1378,6 +1394,7 @@ abstract class BaseLifecycleManager { this.rpcRequestListeners = new HashMap<>(); this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); setupInternalRpcListeners(); + } diff --git a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index f4c5895e4..f08f41f58 100644 --- a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -157,6 +157,12 @@ public class SdlManager extends BaseSdlManager { @Override public void dispose() { + int state = getState(); + if (state == BaseSubManager.SHUTDOWN || state == BaseSubManager.ERROR) { + DebugTool.logInfo(TAG, "SdlManager already disposed"); + return; + } + if (this.permissionManager != null) { this.permissionManager.dispose(); } @@ -203,7 +209,7 @@ public class SdlManager extends BaseSdlManager { @Override public void stop() { - lifecycleManager.getInternalInterface(SdlManager.this).start(); + lifecycleManager.getInternalInterface(SdlManager.this).stop(); } @Override diff --git a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index e29d34640..a23d1ad51 100644 --- a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -39,6 +39,8 @@ import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; import com.smartdevicelink.session.SdlSession; import com.smartdevicelink.transport.BaseTransportConfig; +import static com.smartdevicelink.managers.BaseSubManager.SETTING_UP; + /** * The lifecycle manager creates a central point for all SDL session logic to converge. It should only be used by * the library itself. Usage outside the library is not permitted and will not be protected for in the future. @@ -57,7 +59,9 @@ public class LifecycleManager extends BaseLifecycleManager { @Override void cycle(SdlDisconnectedReason disconnectedReason) { - clean(); + clean(true); + transitionToState(SETTING_UP); + initialize(); if (session != null) { try { session.startSession(); |