diff options
author | Tuan Nguyen <tuan.nguyen617@gmail.com> | 2019-08-23 14:53:15 -0700 |
---|---|---|
committer | Tuan Nguyen <tuan.nguyen617@gmail.com> | 2019-08-23 14:53:15 -0700 |
commit | 0c1653287358d57c86ddff1c011abf91ba3e5eb6 (patch) | |
tree | e702bfbb8a8ffd1e317117ff44c7e382a7313d41 | |
parent | 852563767b4a7dddaca862c1a99002925263e672 (diff) | |
download | sdl_android-0c1653287358d57c86ddff1c011abf91ba3e5eb6.tar.gz |
JavaSE, first batch
- Add BaseEncryptionLifecycleManager
3 files changed, 165 insertions, 3 deletions
diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseEncryptionLifecycleManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseEncryptionLifecycleManager.java new file mode 100644 index 000000000..9c11fdfef --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/BaseEncryptionLifecycleManager.java @@ -0,0 +1,126 @@ +package com.smartdevicelink.managers; + +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.rpc.OnPermissionsChange; +import com.smartdevicelink.proxy.rpc.PermissionItem; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import com.smartdevicelink.util.DebugTool; + +import java.util.*; + +public class BaseEncryptionLifecycleManager extends BaseSubManager { + private ISdl internalInterface; + private OnRPCNotificationListener onPermissionsChangeListener; + private boolean isEncryptionReady; + private CompletionListener securedServiceStartCallback; + + BaseEncryptionLifecycleManager(ISdl isdl) { + super(isdl); + internalInterface = isdl; + + onPermissionsChangeListener = new OnRPCNotificationListener() { + @Override + public void onNotified(RPCNotification notification) { + List<PermissionItem> permissionItems = ((OnPermissionsChange) notification).getPermissionItem(); + Set<String> rpcSet = new HashSet<>(); + boolean appLevelEncryption = Boolean.TRUE.equals(((OnPermissionsChange) notification).getRequireEncryption()); + isAppLevelEncryptionRequired = appLevelEncryption; + if (permissionItems != null && !permissionItems.isEmpty()) { + for (PermissionItem permissionItem : permissionItems) { + if (permissionItem != null) { + if (appLevelEncryption && Boolean.TRUE.equals(permissionItem.getEncryptionRequirement())) { + String rpcName = permissionItem.getRpcName(); + rpcSet.add(rpcName); + } + } + } + } + if (!rpcSet.isEmpty()) { + if (!isEncryptionReady) { + //TODO: start secured service here + startEncryptedRPCService(new CompletionListener() { + @Override + public void onComplete(boolean success) { + //do nothing + } + }); + } + if (!encryptionRequiredRPCs.equals(rpcSet)) { + encryptionRequiredRPCs = rpcSet; + } + } + } + }; + internalInterface.addOnRPCNotificationListener(FunctionID.ON_PERMISSIONS_CHANGE, onPermissionsChangeListener); + internalInterface.addServiceListener(SessionType.RPC, serviceListener); + } + + void startEncryptedRPCService(CompletionListener listener) { + if (isEncryptionReady) { + listener.onComplete(true); + return; + } + securedServiceStartCallback = listener; + //TODO: start secured service, callback is made in serviceListener + } + + void stopEncryptedRPCService(byte sessionID) { + //TODO: stop secured RPC service + } + + boolean isEncryptionReady() { + return isEncryptionReady; + } + + @Override + public void start(CompletionListener listener) { + super.start(listener); + } + + @Override + public void dispose() { + isEncryptionReady = false; + isAppLevelEncryptionRequired = false; + encryptionRequiredRPCs.clear(); + super.dispose(); + } + + private ISdlServiceListener serviceListener = new ISdlServiceListener() { + @Override + public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { + if (SessionType.RPC.equals(type) && session != null) { + isEncryptionReady = isEncrypted; + if (securedServiceStartCallback != null) { + securedServiceStartCallback.onComplete(isEncrypted); + } + DebugTool.logInfo("RPC service started, secured?: " + isEncrypted); + } + } + + @Override + public void onServiceEnded(SdlSession session, SessionType type) { + if (SessionType.RPC.equals(type) && session != null) { + isEncryptionReady = false; + } + DebugTool.logInfo("onServiceEnded, session id: " + (session == null ? "session null" : session.getSessionId()) + + ", session type: " + type.getName()); + } + + @Override + public void onServiceError(SdlSession session, SessionType type, String reason) { + if (SessionType.RPC.equals(type) && session != null) { + isEncryptionReady = false; + if (securedServiceStartCallback != null) { + securedServiceStartCallback.onComplete(false); + } + } + DebugTool.logError("onServiceError, session id: " + (session == null ? "session null" : session.getSessionId()) + + ", session type: " + type.getName()); + } + }; +} diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSubManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSubManager.java index 10477d31a..acc156165 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSubManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSubManager.java @@ -33,10 +33,13 @@ package com.smartdevicelink.managers; import android.support.annotation.NonNull; +import com.smartdevicelink.protocol.enums.FunctionID; import com.smartdevicelink.proxy.interfaces.ISdl; import com.smartdevicelink.transport.utl.TransportRecord; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * <strong>BaseSubManager</strong> <br> @@ -55,12 +58,22 @@ public abstract class BaseSubManager { public static final int SETTING_UP = 0x00, READY = 0x30, LIMITED = 0x50, SHUTDOWN = 0x80, ERROR = 0xC0; protected final ISdl internalInterface; private CompletionListener completionListener; + protected boolean isAppLevelEncryptionRequired; + protected Set<String> encryptionRequiredRPCs = new HashSet<>(); public BaseSubManager(@NonNull ISdl internalInterface){ this.internalInterface = internalInterface; transitionToState(SETTING_UP); } + public boolean getRequiresEncryption() { + return isAppLevelEncryptionRequired; + } + + public boolean getRPCRequiresEncryption(@NonNull FunctionID rpcName) { + return encryptionRequiredRPCs.contains(rpcName.toString()); + } + /** * Starts up a BaseSubManager, and calls provided callback once BaseSubManager is done setting up or failed setup. * @param listener CompletionListener that is called once the BaseSubManager's state is READY, LIMITED, or ERROR diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index 146382de9..48feff5e2 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -87,6 +87,7 @@ public class SdlManager extends BaseSdlManager{ private PermissionManager permissionManager; private FileManager fileManager; private ScreenManager screenManager; + private BaseEncryptionLifecycleManager encryptionManager; // INTERNAL INTERFACE @@ -150,18 +151,21 @@ public class SdlManager extends BaseSdlManager{ @Override void checkState() { if (permissionManager != null && fileManager != null && screenManager != null ){ - if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY){ + if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY + && screenManager.getState() == BaseSubManager.READY && encryptionManager.getState() == BaseSubManager.READY){ DebugTool.logInfo("Starting sdl manager, all sub managers are in ready state"); transitionToState(BaseSubManager.READY); handleQueuedNotifications(); notifyDevListener(null); onReady(); - } else if (permissionManager.getState() == BaseSubManager.ERROR && fileManager.getState() == BaseSubManager.ERROR && screenManager.getState() == BaseSubManager.ERROR){ + } else if (permissionManager.getState() == BaseSubManager.ERROR && fileManager.getState() == BaseSubManager.ERROR + && screenManager.getState() == BaseSubManager.ERROR && encryptionManager.getState() == BaseSubManager.ERROR){ String info = "ERROR starting sdl manager, all sub managers are in error state"; Log.e(TAG, info); transitionToState(BaseSubManager.ERROR); notifyDevListener(info); - } else if (permissionManager.getState() == BaseSubManager.SETTING_UP || fileManager.getState() == BaseSubManager.SETTING_UP || screenManager.getState() == BaseSubManager.SETTING_UP) { + } else if (permissionManager.getState() == BaseSubManager.SETTING_UP || fileManager.getState() == BaseSubManager.SETTING_UP + || screenManager.getState() == BaseSubManager.SETTING_UP || encryptionManager.getState() == BaseSubManager.SETTING_UP) { DebugTool.logInfo("SETTING UP sdl manager, some sub managers are still setting up"); transitionToState(BaseSubManager.SETTING_UP); // No need to notify developer here! @@ -217,11 +221,13 @@ public class SdlManager extends BaseSdlManager{ this.permissionManager = new PermissionManager(_internalInterface); this.fileManager = new FileManager(_internalInterface); this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + this.encryptionManager = new BaseEncryptionLifecycleManager(_internalInterface); // Start sub managers this.permissionManager.start(subManagerListener); this.fileManager.start(subManagerListener); this.screenManager.start(subManagerListener); + this.encryptionManager.start(subManagerListener); } @Override @@ -238,6 +244,10 @@ public class SdlManager extends BaseSdlManager{ this.screenManager.dispose(); } + if (this.encryptionManager != null) { + this.encryptionManager.dispose(); + } + if(managerListener != null){ managerListener.onDestroy(this); managerListener = null; @@ -250,6 +260,19 @@ public class SdlManager extends BaseSdlManager{ // MANAGER GETTERS /** + * Gets the EncryptionManager. <br> + * <strong>Note: EncryptionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> + * @return a BaseEncryptionLifecycleManager object + */ + public BaseEncryptionLifecycleManager getEncryptionManager() { + if (encryptionManager.getState() != BaseSubManager.READY && encryptionManager.getState() != BaseSubManager.LIMITED) { + Log.e(TAG, "EncryptionManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return encryptionManager; + } + + /** * Gets the PermissionManager. <br> * <strong>Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> * @return a PermissionManager object |