From 931aa1bdbe15af338c1593c6d1ec1885b4d0f27c Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 28 May 2020 13:58:20 -0400 Subject: Move code from LifecycleManager to BaseLifecycleManager --- .../managers/lifecycle/BaseLifecycleManager.java | 1461 ++++++++++++++++++++ .../managers/lifecycle/LifecycleManager.java | 1460 +------------------ 2 files changed, 1463 insertions(+), 1458 deletions(-) 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 254b0d505..5a57d722a 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -32,5 +32,1466 @@ package com.smartdevicelink.managers.lifecycle; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; +import android.util.Log; + +import com.smartdevicelink.SdlConnection.ISdlConnectionListener; +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.exception.SdlException; +import com.smartdevicelink.managers.SdlManager; +import com.smartdevicelink.managers.ServiceEncryptionListener; +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.protocol.enums.MessageType; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.SystemCapabilityManager; +import com.smartdevicelink.proxy.interfaces.IAudioStreamListener; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; +import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener; +import com.smartdevicelink.proxy.rpc.OnAppInterfaceUnregistered; +import com.smartdevicelink.proxy.rpc.OnButtonEvent; +import com.smartdevicelink.proxy.rpc.OnButtonPress; +import com.smartdevicelink.proxy.rpc.OnHMIStatus; +import com.smartdevicelink.proxy.rpc.OnSystemRequest; +import com.smartdevicelink.proxy.rpc.RegisterAppInterface; +import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; +import com.smartdevicelink.proxy.rpc.SdlMsgVersion; +import com.smartdevicelink.proxy.rpc.SubscribeButton; +import com.smartdevicelink.proxy.rpc.SystemRequest; +import com.smartdevicelink.proxy.rpc.TTSChunk; +import com.smartdevicelink.proxy.rpc.TemplateColorScheme; +import com.smartdevicelink.proxy.rpc.UnregisterAppInterface; +import com.smartdevicelink.proxy.rpc.VehicleType; +import com.smartdevicelink.proxy.rpc.enums.AppHMIType; +import com.smartdevicelink.proxy.rpc.enums.AppInterfaceUnregisteredReason; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.proxy.rpc.enums.FileType; +import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.RequestType; +import com.smartdevicelink.proxy.rpc.enums.Result; +import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; +import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; +import com.smartdevicelink.security.SdlSecurityBase; +import com.smartdevicelink.streaming.audio.AudioStreamingCodec; +import com.smartdevicelink.streaming.audio.AudioStreamingParams; +import com.smartdevicelink.streaming.video.VideoStreamingParameters; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.util.CorrelationIdGenerator; +import com.smartdevicelink.util.DebugTool; +import com.smartdevicelink.util.FileUtls; +import com.smartdevicelink.util.Version; + +import java.util.HashMap; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.CopyOnWriteArrayList; + abstract class BaseLifecycleManager { + + private static final String TAG = "Lifecycle Manager"; + + public static final Version MAX_SUPPORTED_RPC_VERSION = new Version(6, 0, 0); + + // Protected Correlation IDs + private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, + UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; + + + // Sdl Synchronization Objects + private static final Object RPC_LISTENER_LOCK = new Object(), + ON_UPDATE_LISTENER_LOCK = new Object(), + ON_REQUEST_LISTENER_LOCK = new Object(), + ON_NOTIFICATION_LISTENER_LOCK = new Object(); + + + + SdlSession session; + AppConfig appConfig; + + //protected Version protocolVersion = new Version(1,0,0); + protected Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; + + + private final HashMap> rpcListeners; + private final HashMap rpcResponseListeners; + private final HashMap> rpcNotificationListeners; + private final HashMap> rpcRequestListeners; + + protected final SystemCapabilityManager systemCapabilityManager; + private EncryptionLifecycleManager encryptionLifecycleManager; + + protected RegisterAppInterfaceResponse raiResponse = null; + + private OnHMIStatus currentHMIStatus; + protected boolean firstTimeFull = true; + + final LifecycleListener lifecycleListener; + + private List> _secList = null; + private String authToken; + private Version minimumProtocolVersion; + private Version minimumRPCVersion; + + public BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + + this.lifecycleListener = listener; + + this.rpcListeners = new HashMap<>(); + this.rpcResponseListeners = new HashMap<>(); + this.rpcNotificationListeners = new HashMap<>(); + this.rpcRequestListeners = new HashMap<>(); + + this.appConfig = appConfig; + this.minimumProtocolVersion = appConfig.minimumProtocolVersion; + this.minimumRPCVersion = appConfig.minimumRPCVersion; + this.session = new SdlSession(sdlConnectionListener, config); + + this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); + } + + public void start(){ + try { + setupInternalRpcListeners(); + session.startSession(); + } catch (SdlException e) { + e.printStackTrace(); + } + + } + + /** + * Start a secured RPC service + */ + public void startRPCEncryption() { + if (session != null) { + session.startService(SessionType.RPC, session.getSessionId(), true); + } + } + + public void stop(){ + session.close(); + } + + private Version getProtocolVersion(){ + if (session != null){ + return session.getProtocolVersion(); + } + return new Version(1,0,0); + } + + private void sendRPCs(List messages, final OnMultipleRequestListener listener){ + if(messages != null ){ + for(RPCMessage message : messages){ + // Request Specifics + if(message instanceof RPCRequest){ + RPCRequest request = ((RPCRequest) message); + final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); + request.setCorrelationID(CorrelationIdGenerator.generateId()); + if (listener != null) { + listener.addCorrelationId(request.getCorrelationID()); + request.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onResponse(correlationId, response); + } + if (listener.getSingleRpcResponseListener() != null) { + listener.getSingleRpcResponseListener().onResponse(correlationId, response); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info) { + super.onError(correlationId, resultCode, info); + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onError(correlationId, resultCode, info); + } + if (listener.getSingleRpcResponseListener() != null) { + listener.getSingleRpcResponseListener().onError(correlationId, resultCode, info); + } + } + }); + } + sendRPCMessagePrivate(request); + }else { + // Notifications and Responses + sendRPCMessagePrivate(message); + if (listener != null){ + listener.onUpdate(messages.size()); + if (messages.size() == 0){ + listener.onFinished(); + } + } + } + } + } + } + + private void sendSequentialRPCs(final List messages, final OnMultipleRequestListener listener){ + if (messages != null){ + // Break out of recursion, we have finished the requests + if (messages.size() == 0) { + if(listener != null){ + listener.onFinished(); + } + return; + } + + RPCMessage rpc = messages.remove(0); + + // Request Specifics + if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) rpc; + request.setCorrelationID(CorrelationIdGenerator.generateId()); + + final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); + + request.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onResponse(correlationId, response); + } + if (listener != null) { + listener.onResponse(correlationId, response); + listener.onUpdate(messages.size()); + } + // recurse after onResponse + sendSequentialRPCs(messages, listener); + } + + @Override + public void onError(int correlationId, Result resultCode, String info) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onError(correlationId, resultCode, info); + } + if (listener != null) { + listener.onError(correlationId, resultCode, info); + listener.onUpdate(messages.size()); + + } + // recurse after onError + sendSequentialRPCs(messages, listener); + } + }); + sendRPCMessagePrivate(request); + } else { + // Notifications and Responses + sendRPCMessagePrivate(rpc); + if (listener != null) { + listener.onUpdate(messages.size()); + } + // recurse after sending a notification or response as there is no response. + sendSequentialRPCs(messages, listener); + } + } + } + + /** + * This method is used to ensure all of the methods in this class can remain private and no grantees can be made + * to the developer what methods are available or not. + * + * NOTE: THERE IS NO GURANTEE THIS WILL BE A VALID SYSTEM CAPABILITY MANAGER + * + * @param sdlManager this must be a working manager instance + * @return the system capability manager. + */ + @RestrictTo(RestrictTo.Scope.LIBRARY) + public SystemCapabilityManager getSystemCapabilityManager(SdlManager sdlManager){ + if(sdlManager != null){ + return systemCapabilityManager; + } + return null; + } + + private boolean isConnected(){ + if(session != null){ + return session.getIsConnected(); + }else{ + return false; + } + } + + /** + * Method to retrieve the RegisterAppInterface Response message that was sent back from the + * module. It contains various attributes about the connected module and can be used to adapt + * to different module types and their supported features. + * + * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet + * registered with the module. + */ + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ + return this.raiResponse; + } + + + /** + * Get the current OnHMIStatus + * @return OnHMIStatus object represents the current OnHMIStatus + */ + public OnHMIStatus getCurrentHMIStatus() { + return currentHMIStatus; + } + + private void onClose(String info, Exception e){ + Log.i(TAG, "onClose"); + if(lifecycleListener != null){ + lifecycleListener.onProxyClosed(this, info,e,null); + } + } + + /** + * This method is used to ensure all of the methods in this class can remain private and no grantees can be made + * to the developer what methods are available or not. + * + * @param sdlManager this must be a working manager instance + * @return the internal interface that hooks into this manager + */ + @RestrictTo(RestrictTo.Scope.LIBRARY) + public ISdl getInternalInterface(SdlManager sdlManager) { + if (sdlManager != null) { + return internalInterface; + } + return null; + } + + + /* ******************************************************************************************************* + ********************************** INTERNAL - RPC LISTENERS !! START !! ********************************* + *********************************************************************************************************/ + + private void setupInternalRpcListeners(){ + addRpcListener(FunctionID.REGISTER_APP_INTERFACE, rpcListener); + addRpcListener(FunctionID.ON_HMI_STATUS, rpcListener); + addRpcListener(FunctionID.ON_HASH_CHANGE, rpcListener); + addRpcListener(FunctionID.ON_SYSTEM_REQUEST, rpcListener); + addRpcListener(FunctionID.ON_APP_INTERFACE_UNREGISTERED, rpcListener); + addRpcListener(FunctionID.UNREGISTER_APP_INTERFACE, rpcListener); + } + + + private OnRPCListener rpcListener = new OnRPCListener() { + @Override + public void onReceived(RPCMessage message) { + //Make sure this is a response as expected + FunctionID functionID = message.getFunctionID(); + if (functionID != null) { + switch (functionID) { + case REGISTER_APP_INTERFACE: + //We have begun + Log.i(TAG, "RAI Response"); + raiResponse = (RegisterAppInterfaceResponse) message; + SdlMsgVersion rpcVersion = ((RegisterAppInterfaceResponse) message).getSdlMsgVersion(); + if (rpcVersion != null) { + BaseLifecycleManager.this.rpcSpecVersion = new Version(rpcVersion.getMajorVersion(), rpcVersion.getMinorVersion(), rpcVersion.getPatchVersion()); + } else { + BaseLifecycleManager.this.rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; + } + if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1) { + Log.w(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); + cleanProxy(); + return; + } + processRaiResponse(raiResponse); + systemCapabilityManager.parseRAIResponse(raiResponse); + break; + case ON_HMI_STATUS: + Log.i(TAG, "on hmi status"); + boolean shouldInit = currentHMIStatus == null; + currentHMIStatus = (OnHMIStatus) message; + if (lifecycleListener != null && shouldInit) { + lifecycleListener.onProxyConnected(BaseLifecycleManager.this); + } + break; + case ON_HASH_CHANGE: + break; + case ON_SYSTEM_REQUEST: + final OnSystemRequest onSystemRequest = (OnSystemRequest) message; + if ((onSystemRequest.getUrl() != null) && + (((onSystemRequest.getRequestType() == RequestType.PROPRIETARY) && (onSystemRequest.getFileType() == FileType.JSON)) + || ((onSystemRequest.getRequestType() == RequestType.HTTP) && (onSystemRequest.getFileType() == FileType.BINARY)))) { + Thread handleOffboardTransmissionThread = new Thread() { + @Override + public void run() { + RPCRequest request = PoliciesFetcher.fetchPolicies(onSystemRequest); + if (request != null && isConnected()) { + sendRPCMessagePrivate(request); + } + } + }; + handleOffboardTransmissionThread.start(); + }else if (onSystemRequest.getRequestType() == RequestType.ICON_URL && onSystemRequest.getUrl() != null) { + //Download the icon file and send SystemRequest RPC + Thread handleOffBoardTransmissionThread = new Thread() { + @Override + public void run() { + final String urlHttps = onSystemRequest.getUrl().replaceFirst("http://", "https://"); + byte[] file = FileUtls.downloadFile(urlHttps); + if (file != null) { + SystemRequest systemRequest = new SystemRequest(); + systemRequest.setFileName(onSystemRequest.getUrl()); + systemRequest.setBulkData(file); + systemRequest.setRequestType(RequestType.ICON_URL); + if (isConnected()) { + sendRPCMessagePrivate(systemRequest); + } + } else { + DebugTool.logError("File was null at: " + urlHttps); + } + } + }; + handleOffBoardTransmissionThread.start(); + } + break; + case ON_APP_INTERFACE_UNREGISTERED: + + OnAppInterfaceUnregistered onAppInterfaceUnregistered = (OnAppInterfaceUnregistered) message; + + if (!onAppInterfaceUnregistered.getReason().equals(AppInterfaceUnregisteredReason.LANGUAGE_CHANGE)) { + Log.v(TAG, "on app interface unregistered"); + cleanProxy(); + }else{ + Log.v(TAG, "re-registering for language change"); + processLanguageChange(); + } + break; + case UNREGISTER_APP_INTERFACE: + Log.v(TAG, "unregister app interface"); + cleanProxy(); + break; + } + } + } + + + + }; + + private void processLanguageChange(){ + if (session != null) { + if (session.getIsConnected()) { + session.close(); + } + try { + session.startSession(); + } catch (SdlException e) { + e.printStackTrace(); + } + } + } + + /* ******************************************************************************************************* + ********************************** INTERNAL - RPC LISTENERS !! END !! ********************************* + *********************************************************************************************************/ + + + /* ******************************************************************************************************* + ********************************** METHODS - RPC LISTENERS !! START !! ********************************** + *********************************************************************************************************/ + + private boolean onRPCReceived(final RPCMessage message){ + synchronized(RPC_LISTENER_LOCK){ + if(message == null || message.getFunctionID() == null){ + return false; + } + + final int id = message.getFunctionID().getId(); + CopyOnWriteArrayList listeners = rpcListeners.get(id); + if(listeners!=null && listeners.size()>0) { + for (OnRPCListener listener : listeners) { + listener.onReceived(message); + } + return true; + } + return false; + } + } + + private void addRpcListener(FunctionID id, OnRPCListener listener){ + synchronized(RPC_LISTENER_LOCK){ + if (id != null && listener != null) { + if (!rpcListeners.containsKey(id.getId())) { + rpcListeners.put(id.getId(), new CopyOnWriteArrayList()); + } + + rpcListeners.get(id.getId()).add(listener); + } + } + } + + private boolean removeOnRPCListener(FunctionID id, OnRPCListener listener){ + synchronized(RPC_LISTENER_LOCK){ + if(rpcListeners!= null + && id != null + && listener != null + && rpcListeners.containsKey(id.getId())){ + return rpcListeners.get(id.getId()).remove(listener); + } + } + return false; + } + + /** + * Only call this method for a PutFile response. It will cause a class cast exception if not. + * @param correlationId correlation id of the packet being updated + * @param bytesWritten how many bytes were written + * @param totalSize the total size in bytes + */ + @SuppressWarnings("unused") + private void onPacketProgress(int correlationId, long bytesWritten, long totalSize){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + if(rpcResponseListeners !=null + && rpcResponseListeners.containsKey(correlationId)){ + ((OnPutFileUpdateListener)rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize); + } + } + + } + + /** + * Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code, + *

Will automatically remove the listener for the list of listeners on completion. + * @param msg The RPCResponse message that was received + * @return if a listener was called or not + */ + @SuppressWarnings("UnusedReturnValue") + private boolean onRPCResponseReceived(RPCResponse msg){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + int correlationId = msg.getCorrelationID(); + if(rpcResponseListeners !=null + && rpcResponseListeners.containsKey(correlationId)){ + OnRPCResponseListener listener = rpcResponseListeners.get(correlationId); + if(msg.getSuccess()){ + listener.onResponse(correlationId, msg); + }else{ + listener.onError(correlationId, msg.getResultCode(), msg.getInfo()); + } + rpcResponseListeners.remove(correlationId); + return true; + } + return false; + } + } + + /** + * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id + * @param listener that will get called back when a response is received + * @param correlationId of the RPCRequest that was sent + * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored. + */ + private void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + if(rpcResponseListeners!=null + && listener !=null){ + if(listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE){ + ((OnPutFileUpdateListener)listener).setTotalSize(totalSize); + } + listener.onStart(correlationId); + rpcResponseListeners.put(correlationId, listener); + } + } + } + + @SuppressWarnings("unused") + private HashMap getResponseListeners(){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + return this.rpcResponseListeners; + } + } + + /** + * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC + * service from the module. For example, this should be used to login to a user account. + * @return the string representation of the auth token + */ + public String getAuthToken(){ + return this.authToken; + } + + @SuppressWarnings("UnusedReturnValue") + private boolean onRPCNotificationReceived(RPCNotification notification){ + if(notification == null){ + DebugTool.logError("onRPCNotificationReceived - Notification was null"); + return false; + } + DebugTool.logInfo("onRPCNotificationReceived - " + notification.getFunctionName() ); + + //Before updating any listeners, make sure to do any final updates to the notification RPC now + if(FunctionID.ON_HMI_STATUS.toString().equals(notification.getFunctionName())){ + OnHMIStatus onHMIStatus = (OnHMIStatus) notification; + onHMIStatus.setFirstRun(firstTimeFull); + if (onHMIStatus.getHmiLevel() == HMILevel.HMI_FULL) { + firstTimeFull = false; + } + } + + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + CopyOnWriteArrayList listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName())); + if(listeners!=null && listeners.size()>0) { + for (OnRPCNotificationListener listener : listeners) { + listener.onNotified(notification); + } + return true; + } + return false; + } + } + + /** + * This will add a listener for the specific type of notification. As of now it will only allow + * a single listener per notification function id + * @param notificationId The notification type that this listener is designated for + * @param listener The listener that will be called when a notification of the provided type is received + */ + @SuppressWarnings("unused") + private void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(notificationId != null && listener != null){ + if(!rpcNotificationListeners.containsKey(notificationId.getId())){ + rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList()); + } + rpcNotificationListeners.get(notificationId.getId()).add(listener); + } + } + } + + private boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(rpcNotificationListeners!= null + && notificationId != null + && listener != null + && rpcNotificationListeners.containsKey(notificationId.getId())){ + return rpcNotificationListeners.get(notificationId.getId()).remove(listener); + } + } + return false; + } + + @SuppressWarnings("UnusedReturnValue") + private boolean onRPCRequestReceived(RPCRequest request){ + if(request == null){ + DebugTool.logError("onRPCRequestReceived - request was null"); + return false; + } + DebugTool.logInfo("onRPCRequestReceived - " + request.getFunctionName() ); + + synchronized(ON_REQUEST_LISTENER_LOCK){ + CopyOnWriteArrayList listeners = rpcRequestListeners.get(FunctionID.getFunctionId(request.getFunctionName())); + if(listeners!=null && listeners.size()>0) { + for (OnRPCRequestListener listener : listeners) { + listener.onRequest(request); + } + return true; + } + return false; + } + } + + /** + * This will add a listener for the specific type of request. As of now it will only allow + * a single listener per request function id + * @param requestId The request type that this listener is designated for + * @param listener The listener that will be called when a request of the provided type is received + */ + @SuppressWarnings("unused") + private void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + synchronized(ON_REQUEST_LISTENER_LOCK){ + if(requestId != null && listener != null){ + if(!rpcRequestListeners.containsKey(requestId.getId())){ + rpcRequestListeners.put(requestId.getId(),new CopyOnWriteArrayList()); + } + rpcRequestListeners.get(requestId.getId()).add(listener); + } + } + } + + @SuppressWarnings("UnusedReturnValue") + private boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + synchronized(ON_REQUEST_LISTENER_LOCK){ + if(rpcRequestListeners!= null + && requestId != null + && listener != null + && rpcRequestListeners.containsKey(requestId.getId())){ + return rpcRequestListeners.get(requestId.getId()).remove(listener); + } + } + return false; + } + + /* ******************************************************************************************************* + **************************************** RPC LISTENERS !! END !! **************************************** + *********************************************************************************************************/ + + + + private void sendRPCMessagePrivate(RPCMessage message){ + try { + //FIXME this is temporary until the next major release of the library where OK is removed + if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) message; + if(FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) + || FunctionID.UNSUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) + || FunctionID.BUTTON_PRESS.toString().equals(request.getFunctionName())) { + + ButtonName buttonName = (ButtonName) request.getObject(ButtonName.class, SubscribeButton.KEY_BUTTON_NAME); + + + if (rpcSpecVersion != null) { + if (rpcSpecVersion.getMajor() < 5) { + + if (ButtonName.PLAY_PAUSE.equals(buttonName)) { + request.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.OK); + } + } else { //Newer than version 5.0.0 + if (ButtonName.OK.equals(buttonName)) { + RPCRequest request2 = new RPCRequest(request); + request2.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.PLAY_PAUSE); + request2.setOnRPCResponseListener(request.getOnRPCResponseListener()); + sendRPCMessagePrivate(request2); + return; + } + } + } + + } + } + + + message.format(rpcSpecVersion,true); + byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor()); + + final ProtocolMessage pm = new ProtocolMessage(); + pm.setData(msgBytes); + if (session != null){ + pm.setSessionID(session.getSessionId()); + } + + pm.setMessageType(MessageType.RPC); + pm.setSessionType(SessionType.RPC); + pm.setFunctionID(FunctionID.getFunctionId(message.getFunctionName())); + + if (encryptionLifecycleManager != null && encryptionLifecycleManager.isEncryptionReady() && encryptionLifecycleManager.getRPCRequiresEncryption(message.getFunctionID())) { + pm.setPayloadProtected(true); + } else { + pm.setPayloadProtected(message.isPayloadProtected()); + } + if (pm.getPayloadProtected() && (encryptionLifecycleManager == null || !encryptionLifecycleManager.isEncryptionReady())){ + String errorInfo = "Trying to send an encrypted message and there is no secured service"; + if (message.getMessageType().equals((RPCMessage.KEY_REQUEST))) { + RPCRequest request = (RPCRequest) message; + OnRPCResponseListener listener = ((RPCRequest) message).getOnRPCResponseListener(); + if (listener != null) { + listener.onError(request.getCorrelationID(), Result.ABORTED, errorInfo); + } + } + DebugTool.logWarning(errorInfo); + return; + } + + if(RPCMessage.KEY_REQUEST.equals(message.getMessageType())){ // Request Specifics + pm.setRPCType((byte)0x00); + Integer corrId = ((RPCRequest)message).getCorrelationID(); + if( corrId== null) { + Log.e(TAG, "No correlation ID attached to request. Not sending"); + return; + }else{ + pm.setCorrID(corrId); + + OnRPCResponseListener listener = ((RPCRequest)message).getOnRPCResponseListener(); + if(listener != null){ + addOnRPCResponseListener(listener, corrId, msgBytes.length); + } + } + }else if (RPCMessage.KEY_RESPONSE.equals(message.getMessageType())){ // Response Specifics + RPCResponse response = (RPCResponse) message; + pm.setRPCType((byte)0x01); + if (response.getCorrelationID() == null) { + //Log error here + //throw new SdlException("CorrelationID cannot be null. RPC: " + response.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT); + Log.e(TAG, "No correlation ID attached to response. Not sending"); + return; + } else { + pm.setCorrID(response.getCorrelationID()); + } + }else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics + pm.setRPCType((byte)0x02); + } + + if (message.getBulkData() != null){ + pm.setBulkData(message.getBulkData()); + } + + if(message.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())){ + pm.setPriorityCoefficient(1); + } + + session.sendMessage(pm); + + } catch (OutOfMemoryError e) { + e.printStackTrace(); + } + } + + + + /* ******************************************************************************************************* + *************************************** ISdlConnectionListener START ************************************ + *********************************************************************************************************/ + + final ISdlConnectionListener sdlConnectionListener = new ISdlConnectionListener() { + @Override + public void onTransportDisconnected(String info) { + onClose(info, null); + + } + + @Override + public void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { + if (!availablePrimary) { + onClose(info, null); + } + + } + + @Override + public void onTransportError(String info, Exception e) { + onClose(info, e); + + } + + @Override + public void onProtocolMessageReceived(ProtocolMessage msg) { + //Incoming message + if (SessionType.RPC.equals(msg.getSessionType()) + || SessionType.BULK_DATA.equals(msg.getSessionType())) { + + RPCMessage rpc = RpcConverter.extractRpc(msg, session.getProtocolVersion()); + if (rpc != null) { + String messageType = rpc.getMessageType(); + Log.v(TAG, "RPC received - " + messageType); + + rpc.format(rpcSpecVersion, true); + + onRPCReceived(rpc); + + if (RPCMessage.KEY_RESPONSE.equals(messageType)) { + + onRPCResponseReceived((RPCResponse) rpc); + + } else if (RPCMessage.KEY_NOTIFICATION.equals(messageType)) { + FunctionID functionID = rpc.getFunctionID(); + if (functionID != null && (functionID.equals(FunctionID.ON_BUTTON_PRESS)) || functionID.equals(FunctionID.ON_BUTTON_EVENT)) { + RPCNotification notificationCompat = handleButtonNotificationFormatting(rpc); + if(notificationCompat != null){ + onRPCNotificationReceived((notificationCompat)); + } + } + + onRPCNotificationReceived((RPCNotification) rpc); + + } else if (RPCMessage.KEY_REQUEST.equals(messageType)) { + + onRPCRequestReceived((RPCRequest) rpc); + + } + } else { + Log.w(TAG, "Shouldn't be here"); + } + } + + } + + @Override + public void onProtocolSessionStartedNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID, List rejectedParams) { + Log.w(TAG, "onProtocolSessionStartedNACKed " + sessionID); + } + + @Override + public void onProtocolSessionStarted(SessionType sessionType, byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted) { + + Log.i(TAG, "on protocol session started"); + if (sessionType != null) { + if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { + Log.w(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, session.getSessionId()); + cleanProxy(); + return; + } + + if (sessionType.equals(SessionType.RPC)) { + if (appConfig != null) { + + appConfig.prepare(); + + SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(); + sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor()); + sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor()); + sdlMsgVersion.setPatchVersion(MAX_SUPPORTED_RPC_VERSION.getPatch()); + + RegisterAppInterface rai = new RegisterAppInterface(sdlMsgVersion, + appConfig.getAppName(), appConfig.isMediaApp(), appConfig.getLanguageDesired(), + appConfig.getHmiDisplayLanguageDesired(), appConfig.getAppID()); + rai.setCorrelationID(REGISTER_APP_INTERFACE_CORRELATION_ID); + + rai.setTtsName(appConfig.getTtsName()); + rai.setNgnMediaScreenAppName(appConfig.getNgnMediaScreenAppName()); + rai.setVrSynonyms(appConfig.getVrSynonyms()); + rai.setAppHMIType(appConfig.getAppType()); + rai.setDayColorScheme(appConfig.getDayColorScheme()); + rai.setNightColorScheme(appConfig.getNightColorScheme()); + + //Add device/system info in the future + //TODO attach previous hash id + + sendRPCMessagePrivate(rai); + } else { + Log.e(TAG, "App config was null, soo..."); + } + + + } else { + lifecycleListener.onServiceStarted(sessionType); + } + } + } + + @Override + public void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID) { + + } + + @Override + public void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID) { + + } + + @Override + public void onProtocolError(String info, Exception e) { + DebugTool.logError("Protocol Error - " + info, e); + } + + @Override + public void onHeartbeatTimedOut(byte sessionID) { /* Deprecated */ } + + @Override + public void onProtocolServiceDataACK(SessionType sessionType, int dataSize, byte sessionID) {/* Unused */ } + + + @Override + public void onAuthTokenReceived(String token, byte sessionID) { + BaseLifecycleManager.this.authToken = token; + } + + }; + /* ******************************************************************************************************* + *************************************** ISdlConnectionListener END ************************************ + *********************************************************************************************************/ + + + /* ******************************************************************************************************* + ******************************************** ISdl - START *********************************************** + *********************************************************************************************************/ + + final ISdl internalInterface = new ISdl() { + @Override + public void start() { + BaseLifecycleManager.this.start(); + } + + @Override + public void stop() { + BaseLifecycleManager.this.stop(); + } + + @Override + public boolean isConnected() { + return BaseLifecycleManager.this.session.getIsConnected(); + } + + @Override + public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { + BaseLifecycleManager.this.session.addServiceListener(serviceType,sdlServiceListener); + } + + @Override + public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { + BaseLifecycleManager.this.session.removeServiceListener(serviceType,sdlServiceListener); + } + + @Override + public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { + DebugTool.logWarning("startVideoService is not currently implemented"); + } + + @Override + public void stopVideoService() { + DebugTool.logWarning("stopVideoService is not currently implemented"); + + } + + @Override + public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + DebugTool.logWarning("startVideoStream is not currently implemented"); + return null; + } + + @Override + public void startAudioService(boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params) { + DebugTool.logWarning("startAudioService is not currently implemented"); + } + + @Override + public void startAudioService(boolean encrypted) { + DebugTool.logWarning("startAudioService is not currently implemented"); + + } + + @Override + public void stopAudioService() { + DebugTool.logWarning("stopAudioService is not currently implemented"); + } + + @Override + public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, AudioStreamingParams params) { + DebugTool.logWarning("startAudioStream is not currently implemented"); + return null; + } + + @Override + public void sendRPCRequest(RPCRequest message) { + BaseLifecycleManager.this.sendRPCMessagePrivate(message); + + } + + @Override + public void sendRPC(RPCMessage message) { + if(isConnected()) { + BaseLifecycleManager.this.sendRPCMessagePrivate(message); + } + } + + @Override + public void sendRequests(List rpcs, OnMultipleRequestListener listener) { + BaseLifecycleManager.this.sendRPCs(rpcs,listener); + } + + @Override + public void sendRPCs(List rpcs, OnMultipleRequestListener listener) { + BaseLifecycleManager.this.sendRPCs(rpcs,listener); + } + + @Override + public void sendSequentialRPCs(List rpcs, OnMultipleRequestListener listener) { + BaseLifecycleManager.this.sendSequentialRPCs(rpcs,listener); + } + + @Override + public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + BaseLifecycleManager.this.addOnRPCNotificationListener(notificationId,listener); + } + + @Override + public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + return BaseLifecycleManager.this.removeOnRPCNotificationListener(notificationId,listener); + } + + @Override + public void addOnRPCRequestListener(FunctionID notificationId, OnRPCRequestListener listener) { + BaseLifecycleManager.this.addOnRPCRequestListener(notificationId, listener); + } + + @Override + public boolean removeOnRPCRequestListener(FunctionID notificationId, OnRPCRequestListener listener) { + return BaseLifecycleManager.this.removeOnRPCRequestListener(notificationId, listener); + } + + @Override + public void addOnRPCListener(FunctionID responseId, OnRPCListener listener) { + BaseLifecycleManager.this.addRpcListener(responseId,listener); + } + + @Override + public boolean removeOnRPCListener(FunctionID responseId, OnRPCListener listener) { + return BaseLifecycleManager.this.removeOnRPCListener(responseId,listener); + } + + @Override + public Object getCapability(SystemCapabilityType systemCapabilityType) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + return BaseLifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType); + } else { + return null; + } + } + + @Override + public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + BaseLifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType, scListener); + } + } + + @Override + public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + return BaseLifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType, scListener, forceUpdate); + } else { + return null; + } + } + + @Override + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { + return raiResponse; + } + + @Override + public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + return BaseLifecycleManager.this.systemCapabilityManager.isCapabilitySupported(systemCapabilityType); + } else { + return false; + } + } + + @Override + public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + BaseLifecycleManager.this.systemCapabilityManager.addOnSystemCapabilityListener(systemCapabilityType, listener); + } + } + + @Override + public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { + if (BaseLifecycleManager.this.systemCapabilityManager != null) { + return BaseLifecycleManager.this.systemCapabilityManager.removeOnSystemCapabilityListener(systemCapabilityType, listener); + } else { + return false; + } + } + + @Override + public boolean isTransportForServiceAvailable(SessionType serviceType) { + return BaseLifecycleManager.this.session.isTransportForServiceAvailable(serviceType); + } + + @Override + public SdlMsgVersion getSdlMsgVersion() { + SdlMsgVersion msgVersion = new SdlMsgVersion(rpcSpecVersion.getMajor(), rpcSpecVersion.getMinor()); + msgVersion.setPatchVersion(rpcSpecVersion.getPatch()); + return msgVersion; + } + + @Override + public Version getProtocolVersion() { + return BaseLifecycleManager.this.getProtocolVersion(); + } + + @Override + public void startRPCEncryption() { + BaseLifecycleManager.this.startRPCEncryption(); + } + }; + + /* ******************************************************************************************************* + ********************************************* ISdl - END ************************************************ + *********************************************************************************************************/ + + public interface LifecycleListener{ + void onProxyConnected(BaseLifecycleManager lifeCycleManager); + void onProxyClosed(BaseLifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason); + void onServiceStarted(SessionType sessionType); + void onServiceEnded(SessionType sessionType); + void onError(BaseLifecycleManager lifeCycleManager, String info, Exception e); + } + + public static class AppConfig{ + private String appID, appName, ngnMediaScreenAppName; + private Vector ttsName; + private Vector vrSynonyms; + private boolean isMediaApp = false; + private Language languageDesired, hmiDisplayLanguageDesired; + private Vector appType; + private TemplateColorScheme dayColorScheme, nightColorScheme; + private Version minimumProtocolVersion; + private Version minimumRPCVersion; + + private void prepare(){ + if (getNgnMediaScreenAppName() == null) { + setNgnMediaScreenAppName(getAppName()); + } + + if (getLanguageDesired() == null) { + setLanguageDesired(Language.EN_US); + } + + if (getHmiDisplayLanguageDesired() == null) { + setHmiDisplayLanguageDesired(Language.EN_US); + } + + if (getVrSynonyms() == null) { + setVrSynonyms(new Vector()); + getVrSynonyms().add(getAppName()); + } + } + + public String getAppID() { + return appID; + } + + public void setAppID(String appID) { + this.appID = appID; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getNgnMediaScreenAppName() { + return ngnMediaScreenAppName; + } + + public void setNgnMediaScreenAppName(String ngnMediaScreenAppName) { + this.ngnMediaScreenAppName = ngnMediaScreenAppName; + } + + public Vector getTtsName() { + return ttsName; + } + + public void setTtsName(Vector ttsName) { + this.ttsName = ttsName; + } + + public Vector getVrSynonyms() { + return vrSynonyms; + } + + public void setVrSynonyms(Vector vrSynonyms) { + this.vrSynonyms = vrSynonyms; + } + + public boolean isMediaApp() { + return isMediaApp; + } + + public void setMediaApp(boolean mediaApp) { + isMediaApp = mediaApp; + } + + public Language getLanguageDesired() { + return languageDesired; + } + + public void setLanguageDesired(Language languageDesired) { + this.languageDesired = languageDesired; + } + + public Language getHmiDisplayLanguageDesired() { + return hmiDisplayLanguageDesired; + } + + public void setHmiDisplayLanguageDesired(Language hmiDisplayLanguageDesired) { + this.hmiDisplayLanguageDesired = hmiDisplayLanguageDesired; + } + + public Vector getAppType() { + return appType; + } + + public void setAppType(Vector appType) { + this.appType = appType; + } + + public TemplateColorScheme getDayColorScheme() { + return dayColorScheme; + } + + public void setDayColorScheme(TemplateColorScheme dayColorScheme) { + this.dayColorScheme = dayColorScheme; + } + + public TemplateColorScheme getNightColorScheme() { + return nightColorScheme; + } + + public void setNightColorScheme(TemplateColorScheme nightColorScheme) { + this.nightColorScheme = nightColorScheme; + } + + public Version getMinimumProtocolVersion() { + return minimumProtocolVersion; + } + + /** + * Sets the minimum protocol version that will be permitted to connect. + * If the protocol version of the head unit connected is below this version, + * the app will disconnect with an EndService protocol message and will not register. + * + * @param minimumProtocolVersion a Version object with the minimally accepted Protocol version + */ + public void setMinimumProtocolVersion(Version minimumProtocolVersion) { + this.minimumProtocolVersion = minimumProtocolVersion; + } + + public Version getMinimumRPCVersion() { + return minimumRPCVersion; + } + + /** + * The minimum RPC version that will be permitted to connect. + * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. + * + * @param minimumRPCVersion a Version object with the minimally accepted RPC spec version + */ + public void setMinimumRPCVersion(Version minimumRPCVersion) { + this.minimumRPCVersion = minimumRPCVersion; + } + } + + + /** + * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old + * OK button name. This should be removed during the next major release + * @param notification an RPC message object that should be either an ON_BUTTON_EVENT or ON_BUTTON_PRESS otherwise + * it will be ignored + */ + private RPCNotification handleButtonNotificationFormatting(RPCMessage notification){ + if(FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName()) + || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())){ + + ButtonName buttonName = (ButtonName)notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME); + ButtonName compatBtnName = null; + + if(rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5){ + if(ButtonName.PLAY_PAUSE.equals(buttonName)){ + compatBtnName = ButtonName.OK; + } + }else{ // rpc spec version is either null or less than 5 + if(ButtonName.OK.equals(buttonName)){ + compatBtnName = ButtonName.PLAY_PAUSE; + } + } + + try { + if (compatBtnName != null) { //There is a button name that needs to be swapped out + RPCNotification notification2; + //The following is done because there is currently no way to make a deep copy + //of an RPC. Since this code will be removed, it's ugliness is borderline acceptable. + if (notification instanceof OnButtonEvent) { + OnButtonEvent onButtonEvent = new OnButtonEvent(); + onButtonEvent.setButtonEventMode(((OnButtonEvent) notification).getButtonEventMode()); + onButtonEvent.setCustomButtonID(((OnButtonEvent) notification).getCustomButtonID()); + notification2 = onButtonEvent; + } else if (notification instanceof OnButtonPress) { + OnButtonPress onButtonPress = new OnButtonPress(); + onButtonPress.setButtonPressMode(((OnButtonPress) notification).getButtonPressMode()); + onButtonPress.setCustomButtonName(((OnButtonPress) notification).getCustomButtonName()); + notification2 = onButtonPress; + } else { + return null; + } + + notification2.setParameters(OnButtonEvent.KEY_BUTTON_NAME, compatBtnName); + return notification2; + } + }catch (Exception e){ + //Should never get here + } + } + return null; + } + + private void cleanProxy(){ + if (rpcListeners != null) { + rpcListeners.clear(); + } + if (rpcResponseListeners != null) { + rpcResponseListeners.clear(); + } + if (rpcNotificationListeners != null) { + rpcNotificationListeners.clear(); + } + if (rpcRequestListeners != null) { + rpcRequestListeners.clear(); + } + if (session != null && session.getIsConnected()) { + session.close(); + } + if (encryptionLifecycleManager != null){ + encryptionLifecycleManager.dispose(); + } + } + + @Deprecated + public void setSdlSecurityClassList(List> list) { + _secList = list; + } + + /** + * Sets the security libraries and a callback to notify caller when there is update to encryption service + * @param secList The list of security class(es) + * @param listener The callback object + */ + public void setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { + this._secList = secList; + this.encryptionLifecycleManager = new EncryptionLifecycleManager(internalInterface, listener); + } + + private void processRaiResponse(RegisterAppInterfaceResponse rai) { + if (rai == null) return; + + this.raiResponse = rai; + + VehicleType vt = rai.getVehicleType(); + if (vt == null) return; + + String make = vt.getMake(); + if (make == null) return; + + if (_secList == null) return; + + SdlSecurityBase sec; + + for (Class cls : _secList) { + try { + sec = cls.newInstance(); + } catch (Exception e) { + continue; + } + + if ((sec != null) && (sec.getMakeList() != null)) { + if (sec.getMakeList().contains(make)) { + sec.setAppId(appConfig.getAppID()); + if (session != null) { + session.setSdlSecurity(sec); + sec.handleSdlSession(session); + } + return; + } + } + } + } } diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index 0beb1da0e..e7431ea89 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -32,74 +32,9 @@ package com.smartdevicelink.managers.lifecycle; -import android.support.annotation.NonNull; import android.support.annotation.RestrictTo; -import android.util.Log; -import com.smartdevicelink.SdlConnection.ISdlConnectionListener; -import com.smartdevicelink.SdlConnection.SdlSession; -import com.smartdevicelink.exception.SdlException; -import com.smartdevicelink.managers.SdlManager; -import com.smartdevicelink.managers.ServiceEncryptionListener; -import com.smartdevicelink.marshal.JsonRPCMarshaller; -import com.smartdevicelink.protocol.ProtocolMessage; -import com.smartdevicelink.protocol.enums.FunctionID; -import com.smartdevicelink.protocol.enums.MessageType; -import com.smartdevicelink.protocol.enums.SessionType; -import com.smartdevicelink.proxy.RPCMessage; -import com.smartdevicelink.proxy.RPCNotification; -import com.smartdevicelink.proxy.RPCRequest; -import com.smartdevicelink.proxy.RPCResponse; -import com.smartdevicelink.proxy.SystemCapabilityManager; -import com.smartdevicelink.proxy.interfaces.IAudioStreamListener; -import com.smartdevicelink.proxy.interfaces.ISdl; -import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; -import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; -import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener; -import com.smartdevicelink.proxy.rpc.OnAppInterfaceUnregistered; -import com.smartdevicelink.proxy.rpc.OnButtonEvent; -import com.smartdevicelink.proxy.rpc.OnButtonPress; -import com.smartdevicelink.proxy.rpc.OnHMIStatus; -import com.smartdevicelink.proxy.rpc.OnSystemRequest; -import com.smartdevicelink.proxy.rpc.RegisterAppInterface; -import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; -import com.smartdevicelink.proxy.rpc.SdlMsgVersion; -import com.smartdevicelink.proxy.rpc.SubscribeButton; -import com.smartdevicelink.proxy.rpc.SystemRequest; -import com.smartdevicelink.proxy.rpc.TTSChunk; -import com.smartdevicelink.proxy.rpc.TemplateColorScheme; -import com.smartdevicelink.proxy.rpc.UnregisterAppInterface; -import com.smartdevicelink.proxy.rpc.VehicleType; -import com.smartdevicelink.proxy.rpc.enums.AppHMIType; -import com.smartdevicelink.proxy.rpc.enums.AppInterfaceUnregisteredReason; -import com.smartdevicelink.proxy.rpc.enums.ButtonName; -import com.smartdevicelink.proxy.rpc.enums.FileType; -import com.smartdevicelink.proxy.rpc.enums.HMILevel; -import com.smartdevicelink.proxy.rpc.enums.Language; -import com.smartdevicelink.proxy.rpc.enums.RequestType; -import com.smartdevicelink.proxy.rpc.enums.Result; -import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; -import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; -import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; -import com.smartdevicelink.security.SdlSecurityBase; -import com.smartdevicelink.streaming.audio.AudioStreamingCodec; -import com.smartdevicelink.streaming.audio.AudioStreamingParams; -import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; -import com.smartdevicelink.util.CorrelationIdGenerator; -import com.smartdevicelink.util.DebugTool; -import com.smartdevicelink.util.FileUtls; -import com.smartdevicelink.util.Version; - -import java.util.HashMap; -import java.util.List; -import java.util.Vector; -import java.util.concurrent.CopyOnWriteArrayList; /** * The lifecycle manager creates a central point for all SDL session logic to converge. It should only be used by @@ -107,1398 +42,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { - - private static final String TAG = "Lifecycle Manager"; - - public static final Version MAX_SUPPORTED_RPC_VERSION = new Version(6, 0, 0); - - // Protected Correlation IDs - private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, - UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; - - - // Sdl Synchronization Objects - private static final Object RPC_LISTENER_LOCK = new Object(), - ON_UPDATE_LISTENER_LOCK = new Object(), - ON_REQUEST_LISTENER_LOCK = new Object(), - ON_NOTIFICATION_LISTENER_LOCK = new Object(); - - - - SdlSession session; - AppConfig appConfig; - - //protected Version protocolVersion = new Version(1,0,0); - protected Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; - - - private final HashMap> rpcListeners; - private final HashMap rpcResponseListeners; - private final HashMap> rpcNotificationListeners; - private final HashMap> rpcRequestListeners; - - protected final SystemCapabilityManager systemCapabilityManager; - private EncryptionLifecycleManager encryptionLifecycleManager; - - protected RegisterAppInterfaceResponse raiResponse = null; - - private OnHMIStatus currentHMIStatus; - protected boolean firstTimeFull = true; - - final LifecycleListener lifecycleListener; - - private List> _secList = null; - private String authToken; - private Version minimumProtocolVersion; - private Version minimumRPCVersion; - - public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - - this.lifecycleListener = listener; - - this.rpcListeners = new HashMap<>(); - this.rpcResponseListeners = new HashMap<>(); - this.rpcNotificationListeners = new HashMap<>(); - this.rpcRequestListeners = new HashMap<>(); - - this.appConfig = appConfig; - this.minimumProtocolVersion = appConfig.minimumProtocolVersion; - this.minimumRPCVersion = appConfig.minimumRPCVersion; - this.session = new SdlSession(sdlConnectionListener, config); - - this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); - } - - public void start(){ - try { - setupInternalRpcListeners(); - session.startSession(); - } catch (SdlException e) { - e.printStackTrace(); - } - - } - - /** - * Start a secured RPC service - */ - public void startRPCEncryption() { - if (session != null) { - session.startService(SessionType.RPC, session.getSessionId(), true); - } - } - - public void stop(){ - session.close(); - } - - private Version getProtocolVersion(){ - if (session != null){ - return session.getProtocolVersion(); - } - return new Version(1,0,0); - } - - private void sendRPCs(List messages, final OnMultipleRequestListener listener){ - if(messages != null ){ - for(RPCMessage message : messages){ - // Request Specifics - if(message instanceof RPCRequest){ - RPCRequest request = ((RPCRequest) message); - final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); - request.setCorrelationID(CorrelationIdGenerator.generateId()); - if (listener != null) { - listener.addCorrelationId(request.getCorrelationID()); - request.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (devOnRPCResponseListener != null){ - devOnRPCResponseListener.onResponse(correlationId, response); - } - if (listener.getSingleRpcResponseListener() != null) { - listener.getSingleRpcResponseListener().onResponse(correlationId, response); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - super.onError(correlationId, resultCode, info); - if (devOnRPCResponseListener != null){ - devOnRPCResponseListener.onError(correlationId, resultCode, info); - } - if (listener.getSingleRpcResponseListener() != null) { - listener.getSingleRpcResponseListener().onError(correlationId, resultCode, info); - } - } - }); - } - sendRPCMessagePrivate(request); - }else { - // Notifications and Responses - sendRPCMessagePrivate(message); - if (listener != null){ - listener.onUpdate(messages.size()); - if (messages.size() == 0){ - listener.onFinished(); - } - } - } - } - } - } - - private void sendSequentialRPCs(final List messages, final OnMultipleRequestListener listener){ - if (messages != null){ - // Break out of recursion, we have finished the requests - if (messages.size() == 0) { - if(listener != null){ - listener.onFinished(); - } - return; - } - - RPCMessage rpc = messages.remove(0); - - // Request Specifics - if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) { - RPCRequest request = (RPCRequest) rpc; - request.setCorrelationID(CorrelationIdGenerator.generateId()); - - final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); - - request.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (devOnRPCResponseListener != null){ - devOnRPCResponseListener.onResponse(correlationId, response); - } - if (listener != null) { - listener.onResponse(correlationId, response); - listener.onUpdate(messages.size()); - } - // recurse after onResponse - sendSequentialRPCs(messages, listener); - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - if (devOnRPCResponseListener != null){ - devOnRPCResponseListener.onError(correlationId, resultCode, info); - } - if (listener != null) { - listener.onError(correlationId, resultCode, info); - listener.onUpdate(messages.size()); - - } - // recurse after onError - sendSequentialRPCs(messages, listener); - } - }); - sendRPCMessagePrivate(request); - } else { - // Notifications and Responses - sendRPCMessagePrivate(rpc); - if (listener != null) { - listener.onUpdate(messages.size()); - } - // recurse after sending a notification or response as there is no response. - sendSequentialRPCs(messages, listener); - } - } - } - - /** - * This method is used to ensure all of the methods in this class can remain private and no grantees can be made - * to the developer what methods are available or not. - * - * NOTE: THERE IS NO GURANTEE THIS WILL BE A VALID SYSTEM CAPABILITY MANAGER - * - * @param sdlManager this must be a working manager instance - * @return the system capability manager. - */ - @RestrictTo(RestrictTo.Scope.LIBRARY) - public SystemCapabilityManager getSystemCapabilityManager(SdlManager sdlManager){ - if(sdlManager != null){ - return systemCapabilityManager; - } - return null; - } - - private boolean isConnected(){ - if(session != null){ - return session.getIsConnected(); - }else{ - return false; - } - } - - /** - * Method to retrieve the RegisterAppInterface Response message that was sent back from the - * module. It contains various attributes about the connected module and can be used to adapt - * to different module types and their supported features. - * - * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet - * registered with the module. - */ - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ - return this.raiResponse; - } - - - /** - * Get the current OnHMIStatus - * @return OnHMIStatus object represents the current OnHMIStatus - */ - public OnHMIStatus getCurrentHMIStatus() { - return currentHMIStatus; - } - - private void onClose(String info, Exception e){ - Log.i(TAG, "onClose"); - if(lifecycleListener != null){ - lifecycleListener.onProxyClosed(this, info,e,null); - } - } - - /** - * This method is used to ensure all of the methods in this class can remain private and no grantees can be made - * to the developer what methods are available or not. - * - * @param sdlManager this must be a working manager instance - * @return the internal interface that hooks into this manager - */ - @RestrictTo(RestrictTo.Scope.LIBRARY) - public ISdl getInternalInterface(SdlManager sdlManager) { - if (sdlManager != null) { - return internalInterface; - } - return null; - } - - - /* ******************************************************************************************************* - ********************************** INTERNAL - RPC LISTENERS !! START !! ********************************* - *********************************************************************************************************/ - - private void setupInternalRpcListeners(){ - addRpcListener(FunctionID.REGISTER_APP_INTERFACE, rpcListener); - addRpcListener(FunctionID.ON_HMI_STATUS, rpcListener); - addRpcListener(FunctionID.ON_HASH_CHANGE, rpcListener); - addRpcListener(FunctionID.ON_SYSTEM_REQUEST, rpcListener); - addRpcListener(FunctionID.ON_APP_INTERFACE_UNREGISTERED, rpcListener); - addRpcListener(FunctionID.UNREGISTER_APP_INTERFACE, rpcListener); - } - - - private OnRPCListener rpcListener = new OnRPCListener() { - @Override - public void onReceived(RPCMessage message) { - //Make sure this is a response as expected - FunctionID functionID = message.getFunctionID(); - if (functionID != null) { - switch (functionID) { - case REGISTER_APP_INTERFACE: - //We have begun - Log.i(TAG, "RAI Response"); - raiResponse = (RegisterAppInterfaceResponse) message; - SdlMsgVersion rpcVersion = ((RegisterAppInterfaceResponse) message).getSdlMsgVersion(); - if (rpcVersion != null) { - LifecycleManager.this.rpcSpecVersion = new Version(rpcVersion.getMajorVersion(), rpcVersion.getMinorVersion(), rpcVersion.getPatchVersion()); - } else { - LifecycleManager.this.rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; - } - if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1) { - Log.w(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); - cleanProxy(); - return; - } - processRaiResponse(raiResponse); - systemCapabilityManager.parseRAIResponse(raiResponse); - break; - case ON_HMI_STATUS: - Log.i(TAG, "on hmi status"); - boolean shouldInit = currentHMIStatus == null; - currentHMIStatus = (OnHMIStatus) message; - if (lifecycleListener != null && shouldInit) { - lifecycleListener.onProxyConnected(LifecycleManager.this); - } - break; - case ON_HASH_CHANGE: - break; - case ON_SYSTEM_REQUEST: - final OnSystemRequest onSystemRequest = (OnSystemRequest) message; - if ((onSystemRequest.getUrl() != null) && - (((onSystemRequest.getRequestType() == RequestType.PROPRIETARY) && (onSystemRequest.getFileType() == FileType.JSON)) - || ((onSystemRequest.getRequestType() == RequestType.HTTP) && (onSystemRequest.getFileType() == FileType.BINARY)))) { - Thread handleOffboardTransmissionThread = new Thread() { - @Override - public void run() { - RPCRequest request = PoliciesFetcher.fetchPolicies(onSystemRequest); - if (request != null && isConnected()) { - sendRPCMessagePrivate(request); - } - } - }; - handleOffboardTransmissionThread.start(); - }else if (onSystemRequest.getRequestType() == RequestType.ICON_URL && onSystemRequest.getUrl() != null) { - //Download the icon file and send SystemRequest RPC - Thread handleOffBoardTransmissionThread = new Thread() { - @Override - public void run() { - final String urlHttps = onSystemRequest.getUrl().replaceFirst("http://", "https://"); - byte[] file = FileUtls.downloadFile(urlHttps); - if (file != null) { - SystemRequest systemRequest = new SystemRequest(); - systemRequest.setFileName(onSystemRequest.getUrl()); - systemRequest.setBulkData(file); - systemRequest.setRequestType(RequestType.ICON_URL); - if (isConnected()) { - sendRPCMessagePrivate(systemRequest); - } - } else { - DebugTool.logError("File was null at: " + urlHttps); - } - } - }; - handleOffBoardTransmissionThread.start(); - } - break; - case ON_APP_INTERFACE_UNREGISTERED: - - OnAppInterfaceUnregistered onAppInterfaceUnregistered = (OnAppInterfaceUnregistered) message; - - if (!onAppInterfaceUnregistered.getReason().equals(AppInterfaceUnregisteredReason.LANGUAGE_CHANGE)) { - Log.v(TAG, "on app interface unregistered"); - cleanProxy(); - }else{ - Log.v(TAG, "re-registering for language change"); - processLanguageChange(); - } - break; - case UNREGISTER_APP_INTERFACE: - Log.v(TAG, "unregister app interface"); - cleanProxy(); - break; - } - } - } - - - - }; - - private void processLanguageChange(){ - if (session != null) { - if (session.getIsConnected()) { - session.close(); - } - try { - session.startSession(); - } catch (SdlException e) { - e.printStackTrace(); - } - } - } - - /* ******************************************************************************************************* - ********************************** INTERNAL - RPC LISTENERS !! END !! ********************************* - *********************************************************************************************************/ - - - /* ******************************************************************************************************* - ********************************** METHODS - RPC LISTENERS !! START !! ********************************** - *********************************************************************************************************/ - - private boolean onRPCReceived(final RPCMessage message){ - synchronized(RPC_LISTENER_LOCK){ - if(message == null || message.getFunctionID() == null){ - return false; - } - - final int id = message.getFunctionID().getId(); - CopyOnWriteArrayList listeners = rpcListeners.get(id); - if(listeners!=null && listeners.size()>0) { - for (OnRPCListener listener : listeners) { - listener.onReceived(message); - } - return true; - } - return false; - } - } - - private void addRpcListener(FunctionID id, OnRPCListener listener){ - synchronized(RPC_LISTENER_LOCK){ - if (id != null && listener != null) { - if (!rpcListeners.containsKey(id.getId())) { - rpcListeners.put(id.getId(), new CopyOnWriteArrayList()); - } - - rpcListeners.get(id.getId()).add(listener); - } - } - } - - private boolean removeOnRPCListener(FunctionID id, OnRPCListener listener){ - synchronized(RPC_LISTENER_LOCK){ - if(rpcListeners!= null - && id != null - && listener != null - && rpcListeners.containsKey(id.getId())){ - return rpcListeners.get(id.getId()).remove(listener); - } - } - return false; - } - - /** - * Only call this method for a PutFile response. It will cause a class cast exception if not. - * @param correlationId correlation id of the packet being updated - * @param bytesWritten how many bytes were written - * @param totalSize the total size in bytes - */ - @SuppressWarnings("unused") - private void onPacketProgress(int correlationId, long bytesWritten, long totalSize){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - if(rpcResponseListeners !=null - && rpcResponseListeners.containsKey(correlationId)){ - ((OnPutFileUpdateListener)rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize); - } - } - - } - - /** - * Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code, - *

Will automatically remove the listener for the list of listeners on completion. - * @param msg The RPCResponse message that was received - * @return if a listener was called or not - */ - @SuppressWarnings("UnusedReturnValue") - private boolean onRPCResponseReceived(RPCResponse msg){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - int correlationId = msg.getCorrelationID(); - if(rpcResponseListeners !=null - && rpcResponseListeners.containsKey(correlationId)){ - OnRPCResponseListener listener = rpcResponseListeners.get(correlationId); - if(msg.getSuccess()){ - listener.onResponse(correlationId, msg); - }else{ - listener.onError(correlationId, msg.getResultCode(), msg.getInfo()); - } - rpcResponseListeners.remove(correlationId); - return true; - } - return false; - } - } - - /** - * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id - * @param listener that will get called back when a response is received - * @param correlationId of the RPCRequest that was sent - * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored. - */ - private void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - if(rpcResponseListeners!=null - && listener !=null){ - if(listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE){ - ((OnPutFileUpdateListener)listener).setTotalSize(totalSize); - } - listener.onStart(correlationId); - rpcResponseListeners.put(correlationId, listener); - } - } - } - - @SuppressWarnings("unused") - private HashMap getResponseListeners(){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - return this.rpcResponseListeners; - } - } - - /** - * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC - * service from the module. For example, this should be used to login to a user account. - * @return the string representation of the auth token - */ - public String getAuthToken(){ - return this.authToken; - } - - @SuppressWarnings("UnusedReturnValue") - private boolean onRPCNotificationReceived(RPCNotification notification){ - if(notification == null){ - DebugTool.logError("onRPCNotificationReceived - Notification was null"); - return false; - } - DebugTool.logInfo("onRPCNotificationReceived - " + notification.getFunctionName() ); - - //Before updating any listeners, make sure to do any final updates to the notification RPC now - if(FunctionID.ON_HMI_STATUS.toString().equals(notification.getFunctionName())){ - OnHMIStatus onHMIStatus = (OnHMIStatus) notification; - onHMIStatus.setFirstRun(firstTimeFull); - if (onHMIStatus.getHmiLevel() == HMILevel.HMI_FULL) { - firstTimeFull = false; - } - } - - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ - CopyOnWriteArrayList listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName())); - if(listeners!=null && listeners.size()>0) { - for (OnRPCNotificationListener listener : listeners) { - listener.onNotified(notification); - } - return true; - } - return false; - } - } - - /** - * This will add a listener for the specific type of notification. As of now it will only allow - * a single listener per notification function id - * @param notificationId The notification type that this listener is designated for - * @param listener The listener that will be called when a notification of the provided type is received - */ - @SuppressWarnings("unused") - private void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ - if(notificationId != null && listener != null){ - if(!rpcNotificationListeners.containsKey(notificationId.getId())){ - rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList()); - } - rpcNotificationListeners.get(notificationId.getId()).add(listener); - } - } - } - - private boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ - if(rpcNotificationListeners!= null - && notificationId != null - && listener != null - && rpcNotificationListeners.containsKey(notificationId.getId())){ - return rpcNotificationListeners.get(notificationId.getId()).remove(listener); - } - } - return false; - } - - @SuppressWarnings("UnusedReturnValue") - private boolean onRPCRequestReceived(RPCRequest request){ - if(request == null){ - DebugTool.logError("onRPCRequestReceived - request was null"); - return false; - } - DebugTool.logInfo("onRPCRequestReceived - " + request.getFunctionName() ); - - synchronized(ON_REQUEST_LISTENER_LOCK){ - CopyOnWriteArrayList listeners = rpcRequestListeners.get(FunctionID.getFunctionId(request.getFunctionName())); - if(listeners!=null && listeners.size()>0) { - for (OnRPCRequestListener listener : listeners) { - listener.onRequest(request); - } - return true; - } - return false; - } - } - - /** - * This will add a listener for the specific type of request. As of now it will only allow - * a single listener per request function id - * @param requestId The request type that this listener is designated for - * @param listener The listener that will be called when a request of the provided type is received - */ - @SuppressWarnings("unused") - private void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - synchronized(ON_REQUEST_LISTENER_LOCK){ - if(requestId != null && listener != null){ - if(!rpcRequestListeners.containsKey(requestId.getId())){ - rpcRequestListeners.put(requestId.getId(),new CopyOnWriteArrayList()); - } - rpcRequestListeners.get(requestId.getId()).add(listener); - } - } - } - - @SuppressWarnings("UnusedReturnValue") - private boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - synchronized(ON_REQUEST_LISTENER_LOCK){ - if(rpcRequestListeners!= null - && requestId != null - && listener != null - && rpcRequestListeners.containsKey(requestId.getId())){ - return rpcRequestListeners.get(requestId.getId()).remove(listener); - } - } - return false; - } - - /* ******************************************************************************************************* - **************************************** RPC LISTENERS !! END !! **************************************** - *********************************************************************************************************/ - - - - private void sendRPCMessagePrivate(RPCMessage message){ - try { - //FIXME this is temporary until the next major release of the library where OK is removed - if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { - RPCRequest request = (RPCRequest) message; - if(FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) - || FunctionID.UNSUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) - || FunctionID.BUTTON_PRESS.toString().equals(request.getFunctionName())) { - - ButtonName buttonName = (ButtonName) request.getObject(ButtonName.class, SubscribeButton.KEY_BUTTON_NAME); - - - if (rpcSpecVersion != null) { - if (rpcSpecVersion.getMajor() < 5) { - - if (ButtonName.PLAY_PAUSE.equals(buttonName)) { - request.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.OK); - } - } else { //Newer than version 5.0.0 - if (ButtonName.OK.equals(buttonName)) { - RPCRequest request2 = new RPCRequest(request); - request2.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.PLAY_PAUSE); - request2.setOnRPCResponseListener(request.getOnRPCResponseListener()); - sendRPCMessagePrivate(request2); - return; - } - } - } - - } - } - - - message.format(rpcSpecVersion,true); - byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor()); - - final ProtocolMessage pm = new ProtocolMessage(); - pm.setData(msgBytes); - if (session != null){ - pm.setSessionID(session.getSessionId()); - } - - pm.setMessageType(MessageType.RPC); - pm.setSessionType(SessionType.RPC); - pm.setFunctionID(FunctionID.getFunctionId(message.getFunctionName())); - - if (encryptionLifecycleManager != null && encryptionLifecycleManager.isEncryptionReady() && encryptionLifecycleManager.getRPCRequiresEncryption(message.getFunctionID())) { - pm.setPayloadProtected(true); - } else { - pm.setPayloadProtected(message.isPayloadProtected()); - } - if (pm.getPayloadProtected() && (encryptionLifecycleManager == null || !encryptionLifecycleManager.isEncryptionReady())){ - String errorInfo = "Trying to send an encrypted message and there is no secured service"; - if (message.getMessageType().equals((RPCMessage.KEY_REQUEST))) { - RPCRequest request = (RPCRequest) message; - OnRPCResponseListener listener = ((RPCRequest) message).getOnRPCResponseListener(); - if (listener != null) { - listener.onError(request.getCorrelationID(), Result.ABORTED, errorInfo); - } - } - DebugTool.logWarning(errorInfo); - return; - } - - if(RPCMessage.KEY_REQUEST.equals(message.getMessageType())){ // Request Specifics - pm.setRPCType((byte)0x00); - Integer corrId = ((RPCRequest)message).getCorrelationID(); - if( corrId== null) { - Log.e(TAG, "No correlation ID attached to request. Not sending"); - return; - }else{ - pm.setCorrID(corrId); - - OnRPCResponseListener listener = ((RPCRequest)message).getOnRPCResponseListener(); - if(listener != null){ - addOnRPCResponseListener(listener, corrId, msgBytes.length); - } - } - }else if (RPCMessage.KEY_RESPONSE.equals(message.getMessageType())){ // Response Specifics - RPCResponse response = (RPCResponse) message; - pm.setRPCType((byte)0x01); - if (response.getCorrelationID() == null) { - //Log error here - //throw new SdlException("CorrelationID cannot be null. RPC: " + response.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT); - Log.e(TAG, "No correlation ID attached to response. Not sending"); - return; - } else { - pm.setCorrID(response.getCorrelationID()); - } - }else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics - pm.setRPCType((byte)0x02); - } - - if (message.getBulkData() != null){ - pm.setBulkData(message.getBulkData()); - } - - if(message.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())){ - pm.setPriorityCoefficient(1); - } - - session.sendMessage(pm); - - } catch (OutOfMemoryError e) { - e.printStackTrace(); - } - } - - - - /* ******************************************************************************************************* - *************************************** ISdlConnectionListener START ************************************ - *********************************************************************************************************/ - - final ISdlConnectionListener sdlConnectionListener = new ISdlConnectionListener() { - @Override - public void onTransportDisconnected(String info) { - onClose(info, null); - - } - - @Override - public void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { - if (!availablePrimary) { - onClose(info, null); - } - - } - - @Override - public void onTransportError(String info, Exception e) { - onClose(info, e); - - } - - @Override - public void onProtocolMessageReceived(ProtocolMessage msg) { - //Incoming message - if (SessionType.RPC.equals(msg.getSessionType()) - || SessionType.BULK_DATA.equals(msg.getSessionType())) { - - RPCMessage rpc = RpcConverter.extractRpc(msg, session.getProtocolVersion()); - if (rpc != null) { - String messageType = rpc.getMessageType(); - Log.v(TAG, "RPC received - " + messageType); - - rpc.format(rpcSpecVersion, true); - - onRPCReceived(rpc); - - if (RPCMessage.KEY_RESPONSE.equals(messageType)) { - - onRPCResponseReceived((RPCResponse) rpc); - - } else if (RPCMessage.KEY_NOTIFICATION.equals(messageType)) { - FunctionID functionID = rpc.getFunctionID(); - if (functionID != null && (functionID.equals(FunctionID.ON_BUTTON_PRESS)) || functionID.equals(FunctionID.ON_BUTTON_EVENT)) { - RPCNotification notificationCompat = handleButtonNotificationFormatting(rpc); - if(notificationCompat != null){ - onRPCNotificationReceived((notificationCompat)); - } - } - - onRPCNotificationReceived((RPCNotification) rpc); - - } else if (RPCMessage.KEY_REQUEST.equals(messageType)) { - - onRPCRequestReceived((RPCRequest) rpc); - - } - } else { - Log.w(TAG, "Shouldn't be here"); - } - } - - } - - @Override - public void onProtocolSessionStartedNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID, List rejectedParams) { - Log.w(TAG, "onProtocolSessionStartedNACKed " + sessionID); - } - - @Override - public void onProtocolSessionStarted(SessionType sessionType, byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted) { - - Log.i(TAG, "on protocol session started"); - if (sessionType != null) { - if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { - Log.w(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, session.getSessionId()); - cleanProxy(); - return; - } - - if (sessionType.equals(SessionType.RPC)) { - if (appConfig != null) { - - appConfig.prepare(); - - SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(); - sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor()); - sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor()); - sdlMsgVersion.setPatchVersion(MAX_SUPPORTED_RPC_VERSION.getPatch()); - - RegisterAppInterface rai = new RegisterAppInterface(sdlMsgVersion, - appConfig.getAppName(), appConfig.isMediaApp(), appConfig.getLanguageDesired(), - appConfig.getHmiDisplayLanguageDesired(), appConfig.getAppID()); - rai.setCorrelationID(REGISTER_APP_INTERFACE_CORRELATION_ID); - - rai.setTtsName(appConfig.getTtsName()); - rai.setNgnMediaScreenAppName(appConfig.getNgnMediaScreenAppName()); - rai.setVrSynonyms(appConfig.getVrSynonyms()); - rai.setAppHMIType(appConfig.getAppType()); - rai.setDayColorScheme(appConfig.getDayColorScheme()); - rai.setNightColorScheme(appConfig.getNightColorScheme()); - - //Add device/system info in the future - //TODO attach previous hash id - - sendRPCMessagePrivate(rai); - } else { - Log.e(TAG, "App config was null, soo..."); - } - - - } else { - lifecycleListener.onServiceStarted(sessionType); - } - } - } - - @Override - public void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID) { - - } - - @Override - public void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID) { - - } - - @Override - public void onProtocolError(String info, Exception e) { - DebugTool.logError("Protocol Error - " + info, e); - } - - @Override - public void onHeartbeatTimedOut(byte sessionID) { /* Deprecated */ } - - @Override - public void onProtocolServiceDataACK(SessionType sessionType, int dataSize, byte sessionID) {/* Unused */ } - - - @Override - public void onAuthTokenReceived(String token, byte sessionID) { - LifecycleManager.this.authToken = token; - } - - }; - /* ******************************************************************************************************* - *************************************** ISdlConnectionListener END ************************************ - *********************************************************************************************************/ - - - /* ******************************************************************************************************* - ******************************************** ISdl - START *********************************************** - *********************************************************************************************************/ - - final ISdl internalInterface = new ISdl() { - @Override - public void start() { - LifecycleManager.this.start(); - } - - @Override - public void stop() { - LifecycleManager.this.stop(); - } - - @Override - public boolean isConnected() { - return LifecycleManager.this.session.getIsConnected(); - } - - @Override - public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - LifecycleManager.this.session.addServiceListener(serviceType,sdlServiceListener); - } - - @Override - public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - LifecycleManager.this.session.removeServiceListener(serviceType,sdlServiceListener); - - } - - @Override - public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { - DebugTool.logWarning("startVideoService is not currently implemented"); - - } - - @Override - public void stopVideoService() { - DebugTool.logWarning("stopVideoService is not currently implemented"); - - } - - @Override - public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { - DebugTool.logWarning("startVideoStream is not currently implemented"); - return null; - } - - @Override - public void startAudioService(boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params) { - DebugTool.logWarning("startAudioService is not currently implemented"); - } - - @Override - public void startAudioService(boolean encrypted) { - DebugTool.logWarning("startAudioService is not currently implemented"); - - } - - @Override - public void stopAudioService() { - DebugTool.logWarning("stopAudioService is not currently implemented"); - } - - @Override - public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, AudioStreamingParams params) { - DebugTool.logWarning("startAudioStream is not currently implemented"); - return null; - } - - @Override - public void sendRPCRequest(RPCRequest message) { - LifecycleManager.this.sendRPCMessagePrivate(message); - - } - - @Override - public void sendRPC(RPCMessage message) { - if(isConnected()) { - LifecycleManager.this.sendRPCMessagePrivate(message); - } - } - - @Override - public void sendRequests(List rpcs, OnMultipleRequestListener listener) { - LifecycleManager.this.sendRPCs(rpcs,listener); - } - - @Override - public void sendRPCs(List rpcs, OnMultipleRequestListener listener) { - LifecycleManager.this.sendRPCs(rpcs,listener); - } - - @Override - public void sendSequentialRPCs(List rpcs, OnMultipleRequestListener listener) { - LifecycleManager.this.sendSequentialRPCs(rpcs,listener); - } - - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - LifecycleManager.this.addOnRPCNotificationListener(notificationId,listener); - } - - @Override - public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - return LifecycleManager.this.removeOnRPCNotificationListener(notificationId,listener); - } - - @Override - public void addOnRPCRequestListener(FunctionID notificationId, OnRPCRequestListener listener) { - LifecycleManager.this.addOnRPCRequestListener(notificationId, listener); - } - - @Override - public boolean removeOnRPCRequestListener(FunctionID notificationId, OnRPCRequestListener listener) { - return LifecycleManager.this.removeOnRPCRequestListener(notificationId, listener); - } - - @Override - public void addOnRPCListener(FunctionID responseId, OnRPCListener listener) { - LifecycleManager.this.addRpcListener(responseId,listener); - } - - @Override - public boolean removeOnRPCListener(FunctionID responseId, OnRPCListener listener) { - return LifecycleManager.this.removeOnRPCListener(responseId,listener); - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType) { - if (LifecycleManager.this.systemCapabilityManager != null) { - return LifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType); - } else { - return null; - } - } - - @Override - public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { - if (LifecycleManager.this.systemCapabilityManager != null) { - LifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType, scListener); - } - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) { - if (LifecycleManager.this.systemCapabilityManager != null) { - return LifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType, scListener, forceUpdate); - } else { - return null; - } - } - - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { - return raiResponse; - } - - @Override - public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType) { - if (LifecycleManager.this.systemCapabilityManager != null) { - return LifecycleManager.this.systemCapabilityManager.isCapabilitySupported(systemCapabilityType); - } else { - return false; - } - } - - @Override - public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - if (LifecycleManager.this.systemCapabilityManager != null) { - LifecycleManager.this.systemCapabilityManager.addOnSystemCapabilityListener(systemCapabilityType, listener); - } - } - - @Override - public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - if (LifecycleManager.this.systemCapabilityManager != null) { - return LifecycleManager.this.systemCapabilityManager.removeOnSystemCapabilityListener(systemCapabilityType, listener); - } else { - return false; - } - } - - @Override - public boolean isTransportForServiceAvailable(SessionType serviceType) { - return LifecycleManager.this.session.isTransportForServiceAvailable(serviceType); - } - - @Override - public SdlMsgVersion getSdlMsgVersion() { - SdlMsgVersion msgVersion = new SdlMsgVersion(rpcSpecVersion.getMajor(), rpcSpecVersion.getMinor()); - msgVersion.setPatchVersion(rpcSpecVersion.getPatch()); - return msgVersion; - } - - @Override - public Version getProtocolVersion() { - return LifecycleManager.this.getProtocolVersion(); - } - - @Override - public void startRPCEncryption() { - LifecycleManager.this.startRPCEncryption(); - } - }; - - /* ******************************************************************************************************* - ********************************************* ISdl - END ************************************************ - *********************************************************************************************************/ - - public interface LifecycleListener{ - void onProxyConnected(LifecycleManager lifeCycleManager); - void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason); - void onServiceStarted(SessionType sessionType); - void onServiceEnded(SessionType sessionType); - void onError(LifecycleManager lifeCycleManager, String info, Exception e); - } - - public static class AppConfig{ - private String appID, appName, ngnMediaScreenAppName; - private Vector ttsName; - private Vector vrSynonyms; - private boolean isMediaApp = false; - private Language languageDesired, hmiDisplayLanguageDesired; - private Vector appType; - private TemplateColorScheme dayColorScheme, nightColorScheme; - private Version minimumProtocolVersion; - private Version minimumRPCVersion; - - private void prepare(){ - if (getNgnMediaScreenAppName() == null) { - setNgnMediaScreenAppName(getAppName()); - } - - if (getLanguageDesired() == null) { - setLanguageDesired(Language.EN_US); - } - - if (getHmiDisplayLanguageDesired() == null) { - setHmiDisplayLanguageDesired(Language.EN_US); - } - - if (getVrSynonyms() == null) { - setVrSynonyms(new Vector()); - getVrSynonyms().add(getAppName()); - } - } - - public String getAppID() { - return appID; - } - - public void setAppID(String appID) { - this.appID = appID; - } - - public String getAppName() { - return appName; - } - - public void setAppName(String appName) { - this.appName = appName; - } - - public String getNgnMediaScreenAppName() { - return ngnMediaScreenAppName; - } - - public void setNgnMediaScreenAppName(String ngnMediaScreenAppName) { - this.ngnMediaScreenAppName = ngnMediaScreenAppName; - } - - public Vector getTtsName() { - return ttsName; - } - - public void setTtsName(Vector ttsName) { - this.ttsName = ttsName; - } - - public Vector getVrSynonyms() { - return vrSynonyms; - } - - public void setVrSynonyms(Vector vrSynonyms) { - this.vrSynonyms = vrSynonyms; - } - - public boolean isMediaApp() { - return isMediaApp; - } - - public void setMediaApp(boolean mediaApp) { - isMediaApp = mediaApp; - } - - public Language getLanguageDesired() { - return languageDesired; - } - - public void setLanguageDesired(Language languageDesired) { - this.languageDesired = languageDesired; - } - - public Language getHmiDisplayLanguageDesired() { - return hmiDisplayLanguageDesired; - } - - public void setHmiDisplayLanguageDesired(Language hmiDisplayLanguageDesired) { - this.hmiDisplayLanguageDesired = hmiDisplayLanguageDesired; - } - - public Vector getAppType() { - return appType; - } - - public void setAppType(Vector appType) { - this.appType = appType; - } - - public TemplateColorScheme getDayColorScheme() { - return dayColorScheme; - } - - public void setDayColorScheme(TemplateColorScheme dayColorScheme) { - this.dayColorScheme = dayColorScheme; - } - - public TemplateColorScheme getNightColorScheme() { - return nightColorScheme; - } - - public void setNightColorScheme(TemplateColorScheme nightColorScheme) { - this.nightColorScheme = nightColorScheme; - } - - public Version getMinimumProtocolVersion() { - return minimumProtocolVersion; - } - - /** - * Sets the minimum protocol version that will be permitted to connect. - * If the protocol version of the head unit connected is below this version, - * the app will disconnect with an EndService protocol message and will not register. - * - * @param minimumProtocolVersion a Version object with the minimally accepted Protocol version - */ - public void setMinimumProtocolVersion(Version minimumProtocolVersion) { - this.minimumProtocolVersion = minimumProtocolVersion; - } - - public Version getMinimumRPCVersion() { - return minimumRPCVersion; - } - - /** - * The minimum RPC version that will be permitted to connect. - * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. - * - * @param minimumRPCVersion a Version object with the minimally accepted RPC spec version - */ - public void setMinimumRPCVersion(Version minimumRPCVersion) { - this.minimumRPCVersion = minimumRPCVersion; - } - } - - - /** - * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old - * OK button name. This should be removed during the next major release - * @param notification an RPC message object that should be either an ON_BUTTON_EVENT or ON_BUTTON_PRESS otherwise - * it will be ignored - */ - private RPCNotification handleButtonNotificationFormatting(RPCMessage notification){ - if(FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName()) - || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())){ - - ButtonName buttonName = (ButtonName)notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME); - ButtonName compatBtnName = null; - - if(rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5){ - if(ButtonName.PLAY_PAUSE.equals(buttonName)){ - compatBtnName = ButtonName.OK; - } - }else{ // rpc spec version is either null or less than 5 - if(ButtonName.OK.equals(buttonName)){ - compatBtnName = ButtonName.PLAY_PAUSE; - } - } - - try { - if (compatBtnName != null) { //There is a button name that needs to be swapped out - RPCNotification notification2; - //The following is done because there is currently no way to make a deep copy - //of an RPC. Since this code will be removed, it's ugliness is borderline acceptable. - if (notification instanceof OnButtonEvent) { - OnButtonEvent onButtonEvent = new OnButtonEvent(); - onButtonEvent.setButtonEventMode(((OnButtonEvent) notification).getButtonEventMode()); - onButtonEvent.setCustomButtonID(((OnButtonEvent) notification).getCustomButtonID()); - notification2 = onButtonEvent; - } else if (notification instanceof OnButtonPress) { - OnButtonPress onButtonPress = new OnButtonPress(); - onButtonPress.setButtonPressMode(((OnButtonPress) notification).getButtonPressMode()); - onButtonPress.setCustomButtonName(((OnButtonPress) notification).getCustomButtonName()); - notification2 = onButtonPress; - } else { - return null; - } - - notification2.setParameters(OnButtonEvent.KEY_BUTTON_NAME, compatBtnName); - return notification2; - } - }catch (Exception e){ - //Should never get here - } - } - return null; - } - - private void cleanProxy(){ - if (rpcListeners != null) { - rpcListeners.clear(); - } - if (rpcResponseListeners != null) { - rpcResponseListeners.clear(); - } - if (rpcNotificationListeners != null) { - rpcNotificationListeners.clear(); - } - if (rpcRequestListeners != null) { - rpcRequestListeners.clear(); - } - if (session != null && session.getIsConnected()) { - session.close(); - } - if (encryptionLifecycleManager != null){ - encryptionLifecycleManager.dispose(); - } - } - - @Deprecated - public void setSdlSecurityClassList(List> list) { - _secList = list; - } - - /** - * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) - * @param listener The callback object - */ - public void setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { - this._secList = secList; - this.encryptionLifecycleManager = new EncryptionLifecycleManager(internalInterface, listener); - } - - private void processRaiResponse(RegisterAppInterfaceResponse rai) { - if (rai == null) return; - - this.raiResponse = rai; - - VehicleType vt = rai.getVehicleType(); - if (vt == null) return; - - String make = vt.getMake(); - if (make == null) return; - - if (_secList == null) return; - - SdlSecurityBase sec; - - for (Class cls : _secList) { - try { - sec = cls.newInstance(); - } catch (Exception e) { - continue; - } - - if ((sec != null) && (sec.getMakeList() != null)) { - if (sec.getMakeList().contains(make)) { - sec.setAppId(appConfig.getAppID()); - if (session != null) { - session.setSdlSecurity(sec); - sec.handleSdlSession(session); - } - return; - } - } - } + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + super(appConfig, config, listener); } } -- cgit v1.2.1 From 54e6d7de2a3ee581a33e116412d93e6a83aff515 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 28 May 2020 14:17:54 -0400 Subject: Fix symlinks --- .../lifecycle/EncryptionLifecycleManager.java | 45 ++++++++++++++++++++ .../managers/lifecycle/LifecycleManager.java | 48 ++++++++++++++++++++++ .../java/com/smartdevicelink/managers/lifecycle | 1 + .../lifecycle/LifecycleConfigurationUpdate.java | 1 - .../managers/lifecycle/RpcConverter.java | 1 - 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java create mode 100644 android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java create mode 120000 baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle delete mode 120000 baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleConfigurationUpdate.java delete mode 120000 baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/RpcConverter.java diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java new file mode 100644 index 000000000..1d5915bf4 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.lifecycle; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.ServiceEncryptionListener; +import com.smartdevicelink.proxy.interfaces.ISdl; + +class EncryptionLifecycleManager extends BaseEncryptionLifecycleManager { + + EncryptionLifecycleManager(@NonNull ISdl internalInterface, ServiceEncryptionListener listener) { + super(internalInterface, listener); + } +} 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 new file mode 100644 index 000000000..e7431ea89 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.lifecycle; + +import android.support.annotation.RestrictTo; + +import com.smartdevicelink.transport.BaseTransportConfig; + +/** + * 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. + */ +@RestrictTo(RestrictTo.Scope.LIBRARY) +public class LifecycleManager extends BaseLifecycleManager { + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + super(appConfig, config, listener); + } +} diff --git a/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle b/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle new file mode 120000 index 000000000..d72cada51 --- /dev/null +++ b/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle @@ -0,0 +1 @@ +../../../../../../../base/src/main/java/com/smartdevicelink/managers/lifecycle/ \ No newline at end of file diff --git a/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleConfigurationUpdate.java b/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleConfigurationUpdate.java deleted file mode 120000 index 62dacca1e..000000000 --- a/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleConfigurationUpdate.java +++ /dev/null @@ -1 +0,0 @@ -../../../../../../../../base/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleConfigurationUpdate.java \ No newline at end of file diff --git a/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/RpcConverter.java b/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/RpcConverter.java deleted file mode 120000 index 88f7feccc..000000000 --- a/baseAndroid/src/main/java/com/smartdevicelink/managers/lifecycle/RpcConverter.java +++ /dev/null @@ -1 +0,0 @@ -../../../../../../../../base/src/main/java/com/smartdevicelink/managers/lifecycle/RpcConverter.java \ No newline at end of file -- cgit v1.2.1 From 95ece776d53caa5b5963af0f2338b7c8e76a3f6c Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 28 May 2020 15:18:59 -0400 Subject: Move constructor from BaseLifecycleManager to LifecycleManager --- .../managers/lifecycle/LifecycleManager.java | 5 --- .../managers/lifecycle/BaseLifecycleManager.java | 43 +++++++--------------- .../managers/lifecycle/LifecycleManager.java | 21 ++++++++++- 3 files changed, 32 insertions(+), 37 deletions(-) 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 e7431ea89..acb0fd1dc 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 @@ -34,15 +34,10 @@ package com.smartdevicelink.managers.lifecycle; import android.support.annotation.RestrictTo; -import com.smartdevicelink.transport.BaseTransportConfig; - /** * 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. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { - public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { - super(appConfig, config, listener); - } } 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 5a57d722a..42409bf0a 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -127,12 +127,12 @@ abstract class BaseLifecycleManager { protected Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; - private final HashMap> rpcListeners; - private final HashMap rpcResponseListeners; - private final HashMap> rpcNotificationListeners; - private final HashMap> rpcRequestListeners; + HashMap> rpcListeners; + HashMap rpcResponseListeners; + HashMap> rpcNotificationListeners; + HashMap> rpcRequestListeners; - protected final SystemCapabilityManager systemCapabilityManager; + SystemCapabilityManager systemCapabilityManager; private EncryptionLifecycleManager encryptionLifecycleManager; protected RegisterAppInterfaceResponse raiResponse = null; @@ -140,29 +140,12 @@ abstract class BaseLifecycleManager { private OnHMIStatus currentHMIStatus; protected boolean firstTimeFull = true; - final LifecycleListener lifecycleListener; + LifecycleListener lifecycleListener; private List> _secList = null; private String authToken; - private Version minimumProtocolVersion; - private Version minimumRPCVersion; - - public BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - - this.lifecycleListener = listener; - - this.rpcListeners = new HashMap<>(); - this.rpcResponseListeners = new HashMap<>(); - this.rpcNotificationListeners = new HashMap<>(); - this.rpcRequestListeners = new HashMap<>(); - - this.appConfig = appConfig; - this.minimumProtocolVersion = appConfig.minimumProtocolVersion; - this.minimumRPCVersion = appConfig.minimumRPCVersion; - this.session = new SdlSession(sdlConnectionListener, config); - - this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); - } + Version minimumProtocolVersion; + Version minimumRPCVersion; public void start(){ try { @@ -351,7 +334,7 @@ abstract class BaseLifecycleManager { private void onClose(String info, Exception e){ Log.i(TAG, "onClose"); if(lifecycleListener != null){ - lifecycleListener.onProxyClosed(this, info,e,null); + lifecycleListener.onProxyClosed((LifecycleManager) this, info,e,null); } } @@ -418,7 +401,7 @@ abstract class BaseLifecycleManager { boolean shouldInit = currentHMIStatus == null; currentHMIStatus = (OnHMIStatus) message; if (lifecycleListener != null && shouldInit) { - lifecycleListener.onProxyConnected(BaseLifecycleManager.this); + lifecycleListener.onProxyConnected((LifecycleManager) BaseLifecycleManager.this); } break; case ON_HASH_CHANGE: @@ -1216,11 +1199,11 @@ abstract class BaseLifecycleManager { *********************************************************************************************************/ public interface LifecycleListener{ - void onProxyConnected(BaseLifecycleManager lifeCycleManager); - void onProxyClosed(BaseLifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason); + void onProxyConnected(LifecycleManager lifeCycleManager); + void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason); void onServiceStarted(SessionType sessionType); void onServiceEnded(SessionType sessionType); - void onError(BaseLifecycleManager lifeCycleManager, String info, Exception e); + void onError(LifecycleManager lifeCycleManager, String info, Exception e); } public static class AppConfig{ diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index e7431ea89..0025f3368 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -34,15 +34,32 @@ package com.smartdevicelink.managers.lifecycle; import android.support.annotation.RestrictTo; +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.proxy.SystemCapabilityManager; import com.smartdevicelink.transport.BaseTransportConfig; +import java.util.HashMap; + /** * 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. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { - public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { - super(appConfig, config, listener); + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + + this.lifecycleListener = listener; + + this.rpcListeners = new HashMap<>(); + this.rpcResponseListeners = new HashMap<>(); + this.rpcNotificationListeners = new HashMap<>(); + this.rpcRequestListeners = new HashMap<>(); + + this.appConfig = appConfig; + this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); + this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); + this.session = new SdlSession(sdlConnectionListener, config); + + this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); } } -- cgit v1.2.1 From 59cb907de0b36d130086441ee356a51d4b478990 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 28 May 2020 15:31:56 -0400 Subject: Add Android LifecycleManager constructor --- .../managers/lifecycle/LifecycleManager.java | 33 ++++++++++++++++++++++ .../managers/lifecycle/BaseLifecycleManager.java | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) 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 acb0fd1dc..50cf6dfb3 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 @@ -34,10 +34,43 @@ package com.smartdevicelink.managers.lifecycle; import android.support.annotation.RestrictTo; +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.SdlConnection.SdlSession2; +import com.smartdevicelink.proxy.SystemCapabilityManager; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.transport.MultiplexTransportConfig; +import com.smartdevicelink.transport.TCPTransportConfig; +import com.smartdevicelink.transport.enums.TransportType; + +import java.util.HashMap; + /** * 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. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + + this.lifecycleListener = listener; + + this.rpcListeners = new HashMap<>(); + this.rpcResponseListeners = new HashMap<>(); + this.rpcNotificationListeners = new HashMap<>(); + this.rpcRequestListeners = new HashMap<>(); + + this.appConfig = appConfig; + this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); + this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); + + if (config != null && config.getTransportType().equals(TransportType.MULTIPLEX)) { + this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) config); + }else if(config != null &&config.getTransportType().equals(TransportType.TCP)){ + this.session = new SdlSession2(sdlConnectionListener, (TCPTransportConfig) config); + }else { + this.session = SdlSession.createSession((byte)getProtocolVersion().getMajor(),sdlConnectionListener, config); + } + + this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); + } } 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 42409bf0a..241670bbe 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -170,7 +170,7 @@ abstract class BaseLifecycleManager { session.close(); } - private Version getProtocolVersion(){ + Version getProtocolVersion(){ if (session != null){ return session.getProtocolVersion(); } -- cgit v1.2.1 From e3bcebab830d465227c1c49f9207964880ea7737 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 29 May 2020 13:08:02 -0400 Subject: Setup Android SdlManager to use LifecycleManager --- .../com/smartdevicelink/managers/SdlManager.java | 962 ++------------------- .../managers/lifecycle/LifecycleManager.java | 1 + .../smartdevicelink/managers/BaseSdlManager.java | 647 +++++++++++++- .../com/smartdevicelink/managers/SdlManager.java | 906 +++---------------- 4 files changed, 812 insertions(+), 1704 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 b5a817df8..6be06f673 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 @@ -41,65 +41,22 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import com.smartdevicelink.exception.SdlException; import com.smartdevicelink.managers.audio.AudioStreamManager; import com.smartdevicelink.managers.file.FileManager; -import com.smartdevicelink.managers.file.FileManagerConfig; -import com.smartdevicelink.managers.file.filetypes.SdlArtwork; -import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; import com.smartdevicelink.managers.lockscreen.LockScreenConfig; import com.smartdevicelink.managers.lockscreen.LockScreenManager; import com.smartdevicelink.managers.permission.PermissionManager; import com.smartdevicelink.managers.screen.ScreenManager; import com.smartdevicelink.managers.video.VideoStreamManager; -import com.smartdevicelink.protocol.enums.FunctionID; -import com.smartdevicelink.protocol.enums.SessionType; -import com.smartdevicelink.proxy.RPCMessage; -import com.smartdevicelink.proxy.RPCRequest; -import com.smartdevicelink.proxy.RPCResponse; -import com.smartdevicelink.proxy.SdlProxyBase; -import com.smartdevicelink.proxy.SystemCapabilityManager; -import com.smartdevicelink.proxy.callbacks.OnServiceEnded; -import com.smartdevicelink.proxy.callbacks.OnServiceNACKed; -import com.smartdevicelink.proxy.interfaces.IAudioStreamListener; -import com.smartdevicelink.proxy.interfaces.ISdl; -import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; -import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; -import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener; -import com.smartdevicelink.proxy.rpc.ChangeRegistration; -import com.smartdevicelink.proxy.rpc.OnHMIStatus; -import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; -import com.smartdevicelink.proxy.rpc.SdlMsgVersion; -import com.smartdevicelink.proxy.rpc.SetAppIcon; -import com.smartdevicelink.proxy.rpc.TTSChunk; -import com.smartdevicelink.proxy.rpc.TemplateColorScheme; import com.smartdevicelink.proxy.rpc.enums.AppHMIType; -import com.smartdevicelink.proxy.rpc.enums.Language; -import com.smartdevicelink.proxy.rpc.enums.Result; import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; -import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; -import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; -import com.smartdevicelink.security.SdlSecurityBase; -import com.smartdevicelink.streaming.audio.AudioStreamingCodec; -import com.smartdevicelink.streaming.audio.AudioStreamingParams; -import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.TransportRecord; import com.smartdevicelink.util.DebugTool; -import com.smartdevicelink.util.Version; -import org.json.JSONException; - -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Vector; /** * SDLManager
@@ -114,68 +71,27 @@ import java.util.Vector; * 4. Helper methods */ public class SdlManager extends BaseSdlManager{ - private static final String TAG = "SdlManager"; - private SdlProxyBase proxy; - private SdlArtwork appIcon; private Context context; - private SdlManagerListener managerListener; - private List> sdlSecList; private LockScreenConfig lockScreenConfig; - private FileManagerConfig fileManagerConfig; - private ServiceEncryptionListener serviceEncryptionListener; + // Managers - private PermissionManager permissionManager; - private FileManager fileManager; private LockScreenManager lockScreenManager; - private ScreenManager screenManager; private VideoStreamManager videoStreamManager; private AudioStreamManager audioStreamManager; - // Initialize proxyBridge with anonymous lifecycleListener - private final ProxyBridge proxyBridge = new ProxyBridge(new ProxyBridge.LifecycleListener() { - @Override - public void onProxyConnected() { - DebugTool.logInfo("Proxy is connected. Now initializing."); - changeRegistrationRetry = 0; - checkLifecycleConfiguration(); - initialize(); - } - - @Override - public void onProxyClosed(String info, Exception e, SdlDisconnectedReason reason){ - if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ - dispose(); - } - } - - @Override - public void onServiceEnded(OnServiceEnded serviceEnded){ - - } - - @Override - public void onServiceNACKed(OnServiceNACKed serviceNACKed){ - + @Override + void onProxyClosed(SdlDisconnectedReason reason) { + Log.i(TAG,"Proxy is closed."); + if(managerListener != null){ + managerListener.onDestroy(); } - @Override - public void onError(String info, Exception e){ - + if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ + dispose(); } - }); - - // Sub manager listener - private final CompletionListener subManagerListener = new CompletionListener() { - @Override - public synchronized void onComplete(boolean success) { - if(!success){ - Log.e(TAG, "Sub manager failed to initialize"); - } - checkState(); - } - }; + } @Override void checkState() { @@ -221,88 +137,18 @@ public class SdlManager extends BaseSdlManager{ } } - private void onReady(){ - // Set the app icon - if (SdlManager.this.appIcon != null && SdlManager.this.appIcon.getName() != null) { - if (fileManager != null && fileManager.getState() == BaseSubManager.READY && !fileManager.hasUploadedFile(SdlManager.this.appIcon)) { - fileManager.uploadArtwork(SdlManager.this.appIcon, new CompletionListener() { - @Override - public void onComplete(boolean success) { - if (success) { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - }); - } else { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - } - @Override - protected void checkLifecycleConfiguration(){ - final Language actualLanguage = this.getRegisterAppInterfaceResponse().getLanguage(); - - if (actualLanguage != null && !actualLanguage.equals(hmiLanguage)) { - - final LifecycleConfigurationUpdate lcu = managerListener.managerShouldUpdateLifecycle(actualLanguage); - - if (lcu != null) { - ChangeRegistration changeRegistration = new ChangeRegistration(actualLanguage, actualLanguage); - changeRegistration.setAppName(lcu.getAppName()); - changeRegistration.setNgnMediaScreenAppName(lcu.getShortAppName()); - changeRegistration.setTtsName(lcu.getTtsName()); - changeRegistration.setVrSynonyms(lcu.getVoiceRecognitionCommandNames()); - changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()){ - // go through and change sdlManager properties that were changed via the LCU update - hmiLanguage = actualLanguage; - - if (lcu.getAppName() != null) { - appName = lcu.getAppName(); - } - - if (lcu.getShortAppName() != null) { - shortAppName = lcu.getShortAppName(); - } - - if (lcu.getTtsName() != null) { - ttsChunks = lcu.getTtsName(); - } - - if (lcu.getVoiceRecognitionCommandNames() != null) { - vrSynonyms = lcu.getVoiceRecognitionCommandNames(); - } - } - try { - DebugTool.logInfo(response.serializeJSON().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - DebugTool.logError("Change Registration onError: " + resultCode + " | Info: " + info); - changeRegistrationRetry++; - if (changeRegistrationRetry < MAX_RETRY) { - final Handler handler = new Handler(Looper.getMainLooper()); - handler.postDelayed(new Runnable() { - @Override - public void run() { - checkLifecycleConfiguration(); - DebugTool.logInfo("Retry Change Registration Count: " + changeRegistrationRetry); - } - }, 3000); - } - } - }); - this.sendRPC(changeRegistration); - } + void retryChangeRegistration() { + changeRegistrationRetry++; + if (changeRegistrationRetry < MAX_RETRY) { + final Handler handler = new Handler(Looper.getMainLooper()); + handler.postDelayed(new Runnable() { + @Override + public void run() { + checkLifecycleConfiguration(); + DebugTool.logInfo("Retry Change Registration Count: " + changeRegistrationRetry); + } + }, 3000); } } @@ -367,12 +213,8 @@ public class SdlManager extends BaseSdlManager{ this.audioStreamManager.dispose(); } - if (this.proxy != null && !proxy.isDisposed()) { - try { - this.proxy.dispose(); - } catch (SdlException e) { - DebugTool.logError("Issue disposing proxy in SdlManager", e); - } + if (this.lifecycleManager != null) { + this.lifecycleManager.stop(); } if(managerListener != null){ @@ -385,31 +227,6 @@ public class SdlManager extends BaseSdlManager{ // MANAGER GETTERS - /** - * Gets the PermissionManager.
- * Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a PermissionManager object - */ - public PermissionManager getPermissionManager() { - if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG,"PermissionManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return permissionManager; - } - - /** - * Gets the FileManager.
- * Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a FileManager object - */ - public FileManager getFileManager() { - if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "FileManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return fileManager; - } /** * Gets the VideoStreamManager.
@@ -438,18 +255,6 @@ public class SdlManager extends BaseSdlManager{ return audioStreamManager; } - /** - * Gets the ScreenManager.
- * Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a ScreenManager object - */ - public ScreenManager getScreenManager() { - if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "ScreenManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return screenManager; - } /** * Gets the LockScreenManager.
@@ -464,178 +269,13 @@ public class SdlManager extends BaseSdlManager{ return lockScreenManager; } - /** - * Gets the SystemCapabilityManager.
- * Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a SystemCapabilityManager object - */ - public SystemCapabilityManager getSystemCapabilityManager(){ - return proxy.getSystemCapabilityManager(); - } - /** - * Method to retrieve the RegisterAppInterface Response message that was sent back from the - * module. It contains various attributes about the connected module and can be used to adapt - * to different module types and their supported features. - * - * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet - * registered with the module. - */ - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ - if(proxy != null){ - return proxy.getRegisterAppInterfaceResponse(); - } - return null; - } - - /** - * Get the current OnHMIStatus - * @return OnHMIStatus object represents the current OnHMIStatus - */ - @Override - public OnHMIStatus getCurrentHMIStatus(){ - if(this.proxy !=null ){ - return proxy.getCurrentHMIStatus(); - } - return null; - } - - /** - * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC - * service from the module. For example, this should be used to login to a user account. - * @return the string representation of the auth token - */ - @Override - public String getAuthToken(){ - return this.proxy.getAuthToken(); - } // PROTECTED GETTERS protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; } - protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } - - // SENDING REQUESTS - - /** - * Send RPC Message - * @param message RPCMessage - */ - @Override - public void sendRPC(RPCMessage message) { - try{ - proxy.sendRPC(message); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - - /** - * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests asynchronously, use sendRequests
- * - * NOTE: This will override any listeners on individual RPCs
- * - * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener){ - - List rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - try{ - proxy.sendSequentialRequests(rpcRequestList, listener); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - } - - /** - * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests synchronously, use sendSequentialRPCs
- * - * NOTE: This will override any listeners on individual RPCs
- * - * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendRPCs(List rpcs, final OnMultipleRequestListener listener) { - - List rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - try{ - proxy.sendRequests(rpcRequestList, listener); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - } - - private void handleSdlException(SdlException exception){ - if(exception != null){ - DebugTool.logError("Caught SdlException: " + exception.getSdlExceptionCause()); - // In the future this should handle logic to dispose the manager if it is an unrecoverable error - }else{ - DebugTool.logError("Caught SdlException" ); - } - } - - /** - * Add an OnRPCNotificationListener - * @param listener listener that will be called when a notification is received - */ - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - proxy.addOnRPCNotificationListener(notificationId,listener); - } - - /** - * Remove an OnRPCNotificationListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - proxy.removeOnRPCNotificationListener(notificationId, listener); - } - /** - * Add an OnRPCRequestListener - * @param listener listener that will be called when a request is received - */ - @Override - public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - proxy.addOnRPCRequestListener(requestId,listener); - } - - /** - * Remove an OnRPCRequestListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - proxy.removeOnRPCRequestListener(requestId, listener); - } // LIFECYCLE / OTHER @@ -644,308 +284,46 @@ public class SdlManager extends BaseSdlManager{ /** * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up */ - @SuppressWarnings("unchecked") @Override public void start(){ - if (proxy == null) { - try { - if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ - //Do the thing - MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); - final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); - multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { - @Override - public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { - - //Pass to submanagers that need it - if(videoStreamManager != null){ - videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } + if (lifecycleManager == null) { + if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ + //Do the thing + MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); + final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); + multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { + @Override + public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { - if(audioStreamManager != null){ - audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - //If the developer supplied a listener to start, it is time to call that - if(devListener != null){ - devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); - } + //Pass to submanagers that need it + if(videoStreamManager != null){ + videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); } - }); - //If the requires audio support has not been set, it should be set to true if the - //app is a media app, and false otherwise - if(multiplexTransportConfig.requiresAudioSupport() == null){ - multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); + if(audioStreamManager != null){ + audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + //If the developer supplied a listener to start, it is time to call that + if(devListener != null){ + devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); + } } - } - - proxy = new SdlProxyBase(proxyBridge, context, appName, shortAppName, isMediaApp, hmiLanguage, - hmiLanguage, hmiTypes, appId, transport, vrSynonyms, ttsChunks, dayColorScheme, - nightColorScheme) {}; - proxy.setMinimumProtocolVersion(minimumProtocolVersion); - proxy.setMinimumRPCVersion(minimumRPCVersion); - if (sdlSecList != null && !sdlSecList.isEmpty()) { - proxy.setSdlSecurity(sdlSecList, serviceEncryptionListener); - } - //Setup the notification queue - initNotificationQueue(); + }); - } catch (SdlException e) { - transitionToState(BaseSubManager.ERROR); - if (managerListener != null) { - managerListener.onError("Unable to start manager", e); + //If the requires audio support has not been set, it should be set to true if the + //app is a media app, and false otherwise + if(multiplexTransportConfig.requiresAudioSupport() == null){ + multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); } } - } - } - - protected void setProxy(SdlProxyBase proxy){ - this.proxy = proxy; - } - // INTERNAL INTERFACE - private ISdl _internalInterface = new ISdl() { - @Override - public void start() { - try{ - proxy.initializeProxy(); - }catch (SdlException e){ - e.printStackTrace(); - } + super.start(); } - - @Override - public void stop() { - try{ - proxy.dispose(); - }catch (SdlException e){ - e.printStackTrace(); - } - } - - @Override - public boolean isConnected() { - return proxy.getIsConnected(); - } - - @Override - public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - proxy.addServiceListener(serviceType,sdlServiceListener); - } - - @Override - public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - proxy.removeServiceListener(serviceType,sdlServiceListener); - } - - @Override - public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { - if(proxy.getIsConnected()){ - proxy.startVideoService(encrypted,parameters); - } - } - - @Override - public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){ - if(proxy.getIsConnected()){ - return proxy.startVideoStream(isEncrypted, parameters); - }else{ - DebugTool.logError("Unable to start video stream, proxy not connected"); - return null; - } - } - - @Override - public void stopVideoService() { - if(proxy.getIsConnected()){ - proxy.endVideoStream(); - } - } - - @Override - public void startAudioService(boolean isEncrypted, AudioStreamingCodec codec, - AudioStreamingParams params) { - if(proxy.getIsConnected()){ - proxy.startAudioStream(isEncrypted, codec, params); - } - } - - @Override - public void startAudioService(boolean encrypted) { - if(isConnected()){ - proxy.startService(SessionType.PCM, encrypted); - } - } - - @Override - public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, - AudioStreamingParams params) { - return proxy.startAudioStream(isEncrypted, codec, params); - } - - @Override - public void stopAudioService() { - if(proxy.getIsConnected()){ - proxy.endAudioStream(); - } - } - - @Override - public void sendRPCRequest(RPCRequest message){ - try { - proxy.sendRPC(message); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendRPC(RPCMessage message) { - try { - proxy.sendRPC(message); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendRequests(List rpcs, OnMultipleRequestListener listener) { - try { - proxy.sendRequests(rpcs, listener); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendRPCs(List rpcs, OnMultipleRequestListener listener) { - try { - proxy.sendRequests(rpcs, listener); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendSequentialRPCs(List rpcs, OnMultipleRequestListener listener) { - try { - proxy.sendSequentialRequests(rpcs,listener); - } catch (SdlException e) { - DebugTool.logError("Issue sending sequential RPCs ", e); - } - } - - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - proxy.addOnRPCNotificationListener(notificationId,listener); - } - - @Override - public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - return proxy.removeOnRPCNotificationListener(notificationId,listener); - } - - @Override - public void addOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { - proxy.addOnRPCRequestListener(functionID, listener); - } - - @Override - public boolean removeOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { - return proxy.removeOnRPCRequestListener(functionID, listener); - } - - @Override - public void addOnRPCListener(final FunctionID responseId, final OnRPCListener listener) { - proxyBridge.addRpcListener(responseId, listener); - } - - @Override - public boolean removeOnRPCListener(final FunctionID responseId, final OnRPCListener listener) { - return proxyBridge.removeOnRPCListener(responseId, listener); - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType){ - return proxy.getCapability(systemCapabilityType); - } - - @Override - public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { - proxy.getCapability(systemCapabilityType, scListener); - } - - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { - return proxy.getRegisterAppInterfaceResponse(); - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) { - if (proxy != null && proxy.getSystemCapabilityManager() != null) { - return proxy.getSystemCapabilityManager().getCapability(systemCapabilityType, scListener, forceUpdate); - } - return null; - } - - @Override - public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){ - return proxy.isCapabilitySupported(systemCapabilityType); - } - - @Override - public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - proxy.addOnSystemCapabilityListener(systemCapabilityType, listener); - } - - @Override - public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - return proxy.removeOnSystemCapabilityListener(systemCapabilityType, listener); - } - - @Override - public boolean isTransportForServiceAvailable(SessionType serviceType) { - if(SessionType.NAV.equals(serviceType)){ - return proxy.isVideoStreamTransportAvailable(); - }else if(SessionType.PCM.equals(serviceType)){ - return proxy.isAudioStreamTransportAvailable(); - } - return false; - } - - @Override - public SdlMsgVersion getSdlMsgVersion(){ - try { - return proxy.getSdlMsgVersion(); - } catch (SdlException e) { - e.printStackTrace(); - } - return null; - } - - @Override - public @NonNull Version getProtocolVersion() { - if(proxy.getProtocolVersion() != null){ - return proxy.getProtocolVersion(); - }else{ - return new Version(1,0,0); - } - } - - @Override - public void startRPCEncryption() { - if (proxy != null) { - proxy.startProtectedRPCService(); - } - } - - }; + } // BUILDER - public static class Builder { - SdlManager sdlManager; - + public static class Builder extends BaseSdlManager.Builder{ /** * Builder for the SdlManager. Parameters in the constructor are required. * @param context the current context @@ -954,11 +332,8 @@ public class SdlManager extends BaseSdlManager{ * @param listener a SdlManagerListener object */ public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ - sdlManager = new SdlManager(); + super(appId, appName, listener); setContext(context); - setAppId(appId); - setAppName(appName); - setManagerListener(listener); } /** * Builder for the SdlManager. Parameters in the constructor are required. @@ -968,102 +343,9 @@ public class SdlManager extends BaseSdlManager{ * @param listener a SdlManagerListener object */ public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull BaseTransportConfig transport, @NonNull final SdlManagerListener listener){ - sdlManager = new SdlManager(); + super(appId, appName, listener); setContext(context); - setAppId(appId); - setAppName(appName); setTransportType(transport); - setManagerListener(listener); - } - - /** - * Sets the App ID - * @param appId - */ - public Builder setAppId(@NonNull final String appId){ - sdlManager.appId = appId; - return this; - } - - /** - * Sets the Application Name - * @param appName - */ - public Builder setAppName(@NonNull final String appName){ - sdlManager.appName = appName; - return this; - } - - /** - * Sets the Short Application Name - * @param shortAppName - */ - public Builder setShortAppName(final String shortAppName) { - sdlManager.shortAppName = shortAppName; - return this; - } - - /** - * Sets the minimum protocol version that will be permitted to connect. - * If the protocol version of the head unit connected is below this version, - * the app will disconnect with an EndService protocol message and will not register. - * @param minimumProtocolVersion the minimum Protocol spec version that should be accepted - */ - public Builder setMinimumProtocolVersion(final Version minimumProtocolVersion) { - sdlManager.minimumProtocolVersion = minimumProtocolVersion; - return this; - } - - /** - * The minimum RPC version that will be permitted to connect. - * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. - * @param minimumRPCVersion the minimum RPC spec version that should be accepted - */ - public Builder setMinimumRPCVersion(final Version minimumRPCVersion) { - sdlManager.minimumRPCVersion = minimumRPCVersion; - return this; - } - - /** - * Sets the Language of the App - * @param hmiLanguage the desired language to be used on the display/HMI of the connected module - */ - public Builder setLanguage(final Language hmiLanguage){ - sdlManager.hmiLanguage = hmiLanguage; - return this; - } - - /** - * Sets the TemplateColorScheme for daytime - * @param dayColorScheme color scheme that will be used (if supported) when the display is - * in a "Day Mode" or similar. Should comprise of colors that contrast - * well during the day under sunlight. - */ - public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){ - sdlManager.dayColorScheme = dayColorScheme; - return this; - } - - /** - * Sets the TemplateColorScheme for nighttime - * @param nightColorScheme color scheme that will be used (if supported) when the display is - * in a "Night Mode" or similar. Should comprise of colors that - * contrast well during the night and are not brighter than average. - */ - public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){ - sdlManager.nightColorScheme = nightColorScheme; - return this; - } - - /** - * Sets the FileManagerConfig for the session.
- * Note: If not set, the default configuration value of 1 will be set for - * artworkRetryCount and fileRetryCount in FileManagerConfig - * @param fileManagerConfig - configuration options - */ - public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){ - sdlManager.fileManagerConfig = fileManagerConfig; - return this; } /** @@ -1076,63 +358,6 @@ public class SdlManager extends BaseSdlManager{ return this; } - /** - * Sets the icon for the app on head unit / In-Vehicle-Infotainment system
- * @param sdlArtwork the icon that will be used to represent this application on the - * connected module - */ - public Builder setAppIcon(final SdlArtwork sdlArtwork){ - sdlManager.appIcon = sdlArtwork; - return this; - } - - /** - * Sets the vector of AppHMIType
- * Note: This should be an ordered list from most -> least relevant - * @param hmiTypes HMI types that represent this application. For example, if the app is a - * music player, the MEDIA HMIType should be included. - */ - public Builder setAppTypes(final Vector hmiTypes){ - - sdlManager.hmiTypes = hmiTypes; - - if (hmiTypes != null) { - sdlManager.isMediaApp = hmiTypes.contains(AppHMIType.MEDIA); - } - - return this; - } - - /** - * Sets the voice recognition synonyms that can be used to identify this application. - * @param vrSynonyms a vector of Strings that can be associated with this app. For example the app's name should - * be included as well as any phonetic spellings of the app name that might help the on-board - * VR system associated a users spoken word with the supplied synonyms. - */ - public Builder setVrSynonyms(final Vector vrSynonyms) { - sdlManager.vrSynonyms = vrSynonyms; - return this; - } - - /** - * Sets the Text-To-Speech Name of the application. These TTSChunks might be used by the module as an audio - * representation of the app's name. - * @param ttsChunks the TTS chunks that can represent this app's name - */ - public Builder setTtsName(final Vector ttsChunks) { - sdlManager.ttsChunks = ttsChunks; - return this; - } - - /** - * This Object type may change with the transport refactor - * Sets the BaseTransportConfig - * @param transport the type of transport that should be used for this SdlManager instance. - */ - public Builder setTransportType(@NonNull BaseTransportConfig transport){ - sdlManager.transport = transport; - return this; - } /** * Sets the Context @@ -1143,45 +368,6 @@ public class SdlManager extends BaseSdlManager{ return this; } - /** - * Sets the Security library - * @param secList The list of security class(es) - */ - @Deprecated - public Builder setSdlSecurity(List> secList) { - sdlManager.sdlSecList = secList; - return this; - } - - /** - * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) - * @param listener The callback object - */ - public Builder setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { - sdlManager.sdlSecList = secList; - sdlManager.serviceEncryptionListener = listener; - return this; - } - - /** - * Set the SdlManager Listener - * @param listener the listener - */ - public Builder setManagerListener(@NonNull final SdlManagerListener listener){ - sdlManager.managerListener = listener; - return this; - } - - /** - * Set RPCNotification listeners. SdlManager will preload these listeners before any RPCs are sent/received. - * @param listeners a map of listeners that will be called when a notification is received. - * Key represents the FunctionID of the notification and value represents the listener - */ - public Builder setRPCNotificationListeners(Map listeners){ - sdlManager.onRPCNotificationListeners = listeners; - return this; - } /** * Build SdlManager ang get it ready to be started @@ -1189,64 +375,18 @@ public class SdlManager extends BaseSdlManager{ * @return SdlManager instance that is ready to be started */ public SdlManager build() { - - if (sdlManager.appName == null) { - throw new IllegalArgumentException("You must specify an app name by calling setAppName"); - } - - if (sdlManager.appId == null) { - throw new IllegalArgumentException("You must specify an app ID by calling setAppId"); - } - - if (sdlManager.managerListener == null) { - throw new IllegalArgumentException("You must set a SdlManagerListener object"); - } - if (sdlManager.transport == null) { throw new IllegalArgumentException("You must set a transport type object"); } - if (sdlManager.hmiTypes == null) { - Vector hmiTypesDefault = new Vector<>(); - hmiTypesDefault.add(AppHMIType.DEFAULT); - sdlManager.hmiTypes = hmiTypesDefault; - sdlManager.isMediaApp = false; - } - if (sdlManager.lockScreenConfig == null){ // if lock screen params are not set, use default sdlManager.lockScreenConfig = new LockScreenConfig(); } - if(sdlManager.fileManagerConfig == null){ - //if FileManagerConfig is not set use default - sdlManager.fileManagerConfig = new FileManagerConfig(); - } - - if (sdlManager.hmiLanguage == null){ - sdlManager.hmiLanguage = Language.EN_US; - } - - if (sdlManager.minimumProtocolVersion == null){ - sdlManager.minimumProtocolVersion = new Version("1.0.0"); - } - - if (sdlManager.minimumRPCVersion == null){ - sdlManager.minimumRPCVersion = new Version("1.0.0"); - } - - sdlManager.transitionToState(BaseSubManager.SETTING_UP); + super.build(); return sdlManager; } } - - /** - * Start a secured RPC service - */ - public void startRPCEncryption() { - if (proxy != null) { - proxy.startProtectedRPCService(); - } - } } 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 50cf6dfb3..71f3adc8f 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 @@ -47,6 +47,7 @@ import java.util.HashMap; /** * 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. + * @author Bilal Alsharifi. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 95ec756b1..cc5494ff9 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -31,24 +31,46 @@ */ package com.smartdevicelink.managers; +import android.support.annotation.NonNull; import android.util.Log; +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.managers.file.FileManagerConfig; +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; +import com.smartdevicelink.managers.lifecycle.LifecycleManager; +import com.smartdevicelink.managers.permission.PermissionManager; +import com.smartdevicelink.managers.screen.ScreenManager; import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.protocol.enums.SessionType; import com.smartdevicelink.proxy.RPCMessage; import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.SystemCapabilityManager; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.rpc.ChangeRegistration; import com.smartdevicelink.proxy.rpc.OnHMIStatus; import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; +import com.smartdevicelink.proxy.rpc.SetAppIcon; import com.smartdevicelink.proxy.rpc.TTSChunk; import com.smartdevicelink.proxy.rpc.TemplateColorScheme; import com.smartdevicelink.proxy.rpc.enums.AppHMIType; import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.Result; +import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; +import com.smartdevicelink.security.SdlSecurityBase; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.util.DebugTool; import com.smartdevicelink.util.Version; +import org.json.JSONException; + +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Queue; @@ -58,13 +80,9 @@ import java.util.concurrent.ConcurrentLinkedQueue; abstract class BaseSdlManager { - private static final String TAG = "BaseSubManager"; - + static final String TAG = "BaseSubManager"; final Object STATE_LOCK = new Object(); int state = -1; - - static final int MAX_RETRY = 3; - int changeRegistrationRetry = 0; String appId, appName, shortAppName; boolean isMediaApp; Language hmiLanguage; @@ -75,10 +93,79 @@ abstract class BaseSdlManager { TemplateColorScheme dayColorScheme, nightColorScheme; Version minimumProtocolVersion; Version minimumRPCVersion; - Queue queuedNotifications = null; OnRPCNotificationListener queuedNotificationListener = null; Map onRPCNotificationListeners; + SdlArtwork appIcon; + SdlManagerListener managerListener; + List> sdlSecList; + ServiceEncryptionListener serviceEncryptionListener; + FileManagerConfig fileManagerConfig; + int changeRegistrationRetry = 0; + static final int MAX_RETRY = 3; + + // Managers + LifecycleManager lifecycleManager; + PermissionManager permissionManager; + FileManager fileManager; + ScreenManager screenManager; + + + // INTERNAL INTERFACE + /** + * This is from the LifeCycleManager directly. In the future if there is a reason to be a man in the middle + * the SdlManager could create it's own, however right now it was only a duplication of logic tied to the LCM. + */ + ISdl _internalInterface; + + + // Initialize with anonymous lifecycleListener + final LifecycleManager.LifecycleListener lifecycleListener = new LifecycleManager.LifecycleListener() { + boolean initStarted = false; + @Override + public void onProxyConnected(LifecycleManager lifeCycleManager) { + Log.i(TAG,"Proxy is connected. Now initializing."); + synchronized (this){ + if(!initStarted){ + changeRegistrationRetry = 0; + checkLifecycleConfiguration(); + initialize(); + initStarted = true; + } + } + } + @Override + public void onServiceStarted(SessionType sessionType){ + + } + + @Override + public void onServiceEnded(SessionType sessionType){ + + } + + @Override + public void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason) { + BaseSdlManager.this.onProxyClosed(reason); + } + + + @Override + public void onError(LifecycleManager lifeCycleManager, String info, Exception e) { + + } + }; + + // Sub manager listener + final CompletionListener subManagerListener = new CompletionListener() { + @Override + public synchronized void onComplete(boolean success) { + if(!success){ + Log.e(TAG, "Sub manager failed to initialize"); + } + checkState(); + } + }; // PROTECTED GETTERS protected String getAppName() { return appName; } @@ -105,6 +192,59 @@ abstract class BaseSdlManager { protected BaseTransportConfig getTransport() { return transport; } + protected void checkLifecycleConfiguration() { + final Language actualLanguage = lifecycleManager.getRegisterAppInterfaceResponse().getLanguage(); + + if (actualLanguage != null && !actualLanguage.equals(hmiLanguage)) { + + final LifecycleConfigurationUpdate lcu = managerListener.managerShouldUpdateLifecycle(actualLanguage); + + if (lcu != null) { + ChangeRegistration changeRegistration = new ChangeRegistration(actualLanguage, actualLanguage); + changeRegistration.setAppName(lcu.getAppName()); + changeRegistration.setNgnMediaScreenAppName(lcu.getShortAppName()); + changeRegistration.setTtsName(lcu.getTtsName()); + changeRegistration.setVrSynonyms(lcu.getVoiceRecognitionCommandNames()); + changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (response.getSuccess()) { + // go through and change sdlManager properties that were changed via the LCU update + hmiLanguage = actualLanguage; + + if (lcu.getAppName() != null) { + appName = lcu.getAppName(); + } + + if (lcu.getShortAppName() != null) { + shortAppName = lcu.getShortAppName(); + } + + if (lcu.getTtsName() != null) { + ttsChunks = lcu.getTtsName(); + } + + if (lcu.getVoiceRecognitionCommandNames() != null) { + vrSynonyms = lcu.getVoiceRecognitionCommandNames(); + } + } + try { + Log.v(TAG, response.serializeJSON().toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info) { + DebugTool.logError("Change Registration onError: " + resultCode + " | Info: " + info); + retryChangeRegistration(); + } + }); + _internalInterface.sendRPC(changeRegistration); + } + } + } /** * Get the current state for the SdlManager @@ -181,39 +321,504 @@ abstract class BaseSdlManager { } } + abstract void retryChangeRegistration(); + abstract void onProxyClosed(SdlDisconnectedReason reason); abstract void checkState(); + abstract void initialize(); + public abstract void dispose(); - protected abstract void initialize(); - protected abstract void checkLifecycleConfiguration(); - //Public abstract API - public abstract void start(); - public abstract void dispose(); - public abstract void sendRPC(RPCMessage message); - public abstract void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener); - public abstract void sendRPCs(List rpcs, final OnMultipleRequestListener listener); - public abstract RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(); - public abstract OnHMIStatus getCurrentHMIStatus(); - public abstract String getAuthToken(); - public abstract void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener); + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @SuppressWarnings("unchecked") + public void start(){ + LifecycleManager.AppConfig appConfig = new LifecycleManager.AppConfig(); + appConfig.setAppName(appName); + //short app name + appConfig.setMediaApp(isMediaApp); + appConfig.setHmiDisplayLanguageDesired(hmiLanguage); + appConfig.setLanguageDesired(hmiLanguage); + appConfig.setAppType(hmiTypes); + appConfig.setVrSynonyms(vrSynonyms); + appConfig.setTtsName(ttsChunks); + appConfig.setDayColorScheme(dayColorScheme); + appConfig.setNightColorScheme(nightColorScheme); + appConfig.setAppID(appId); + appConfig.setMinimumProtocolVersion(minimumProtocolVersion); + appConfig.setMinimumRPCVersion(minimumRPCVersion); + + lifecycleManager = new LifecycleManager(appConfig, transport, lifecycleListener); + _internalInterface = lifecycleManager.getInternalInterface((SdlManager) BaseSdlManager.this); + + if (sdlSecList != null && !sdlSecList.isEmpty()) { + lifecycleManager.setSdlSecurity(sdlSecList, serviceEncryptionListener); + } + + //Setup the notification queue + initNotificationQueue(); + + lifecycleManager.start(); + } + + + void onReady(){ + // Set the app icon + if (BaseSdlManager.this.appIcon != null && BaseSdlManager.this.appIcon.getName() != null) { + if (fileManager != null && fileManager.getState() == BaseSubManager.READY && !fileManager.hasUploadedFile(BaseSdlManager.this.appIcon)) { + fileManager.uploadArtwork(BaseSdlManager.this.appIcon, new CompletionListener() { + @Override + public void onComplete(boolean success) { + if (success) { + SetAppIcon msg = new SetAppIcon(BaseSdlManager.this.appIcon.getName()); + _internalInterface.sendRPCRequest(msg); + } + } + }); + } else { + SetAppIcon msg = new SetAppIcon(BaseSdlManager.this.appIcon.getName()); + _internalInterface.sendRPCRequest(msg); + } + } + } + + + + + + + + // MANAGER GETTERS + /** + * Gets the PermissionManager.
+ * Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * @return a PermissionManager object + */ + public PermissionManager getPermissionManager() { + if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED){ + Log.e(TAG,"PermissionManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return permissionManager; + } + + /** + * Gets the FileManager.
+ * Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * @return a FileManager object + */ + public FileManager getFileManager() { + if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED){ + Log.e(TAG, "FileManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return fileManager; + } + + /** + * Gets the ScreenManager.
+ * Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * @return a ScreenManager object + */ + public ScreenManager getScreenManager() { + if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED){ + Log.e(TAG, "ScreenManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return screenManager; + } + + /** + * Gets the SystemCapabilityManager.
+ * Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * @return a SystemCapabilityManager object + */ + public SystemCapabilityManager getSystemCapabilityManager(){ + return lifecycleManager.getSystemCapabilityManager((SdlManager) this); + } + + /** + * Method to retrieve the RegisterAppInterface Response message that was sent back from the + * module. It contains various attributes about the connected module and can be used to adapt + * to different module types and their supported features. + * + * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet + * registered with the module. + */ + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ + if(lifecycleManager != null){ + return lifecycleManager.getRegisterAppInterfaceResponse(); + } + return null; + } + + /** + * Get the current OnHMIStatus + * @return OnHMIStatus object represents the current OnHMIStatus + */ + public OnHMIStatus getCurrentHMIStatus(){ + if(this.lifecycleManager !=null ){ + return lifecycleManager.getCurrentHMIStatus(); + } + return null; + } + + // PROTECTED GETTERS + + protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } + + /** + * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC + * service from the module. For example, this should be used to login to a user account. + * @return the string representation of the auth token + */ + public String getAuthToken(){ + return this.lifecycleManager.getAuthToken(); + } + + // SENDING REQUESTS + + /** + * Send RPC Message
+ * @param message RPCMessage + */ + public void sendRPC(RPCMessage message) { + _internalInterface.sendRPC(message); + } + + /** + * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. + * For sending requests asynchronously, use sendRequests
+ * + * NOTE: This will override any listeners on individual RPCs
+ * + * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out + * + * @param rpcs is the list of RPCMessages being sent + * @param listener listener for updates and completions + */ + public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener){ + + List rpcRequestList = new ArrayList<>(); + for (int i = 0; i < rpcs.size(); i++) { + if (rpcs.get(i) instanceof RPCRequest){ + rpcRequestList.add((RPCRequest)rpcs.get(i)); + } + } + + if (rpcRequestList.size() > 0) { + _internalInterface.sendSequentialRPCs(rpcRequestList, listener); + } + } + + /** + * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener. + * For sending requests synchronously, use sendSequentialRPCs
+ * + * NOTE: This will override any listeners on individual RPCs
+ * + * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out + * + * @param rpcs is the list of RPCMessages being sent + * @param listener listener for updates and completions + */ + public void sendRPCs(List rpcs, final OnMultipleRequestListener listener) { + + List rpcRequestList = new ArrayList<>(); + for (int i = 0; i < rpcs.size(); i++) { + if (rpcs.get(i) instanceof RPCRequest){ + rpcRequestList.add((RPCRequest)rpcs.get(i)); + } + } + + if (rpcRequestList.size() > 0) { + _internalInterface.sendRequests(rpcRequestList,listener); + } + } + + /** + * Add an OnRPCNotificationListener + * @param listener listener that will be called when a notification is received + */ + public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + _internalInterface.addOnRPCNotificationListener(notificationId,listener); + } /** * Remove an OnRPCNotificationListener * @param listener listener that was previously added */ - public abstract void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener); + public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + _internalInterface.removeOnRPCNotificationListener(notificationId, listener); + } /** * Add an OnRPCRequestListener * @param listener listener that will be called when a request is received */ - public abstract void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener); + public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + _internalInterface.addOnRPCRequestListener(requestId,listener); + } /** * Remove an OnRPCRequestListener * @param listener listener that was previously added */ - public abstract void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener); + public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + _internalInterface.removeOnRPCRequestListener(requestId, listener); + } + + // LIFECYCLE / OTHER + + + + // BUILDER + public static class Builder { + SdlManager sdlManager; + + Builder(@NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener) { + sdlManager = new SdlManager(); + setAppId(appId); + setAppName(appName); + setManagerListener(listener); + } + /** + * Sets the App ID + * @param appId String representation of the App ID retreived from the SDL Developer Portal + */ + public Builder setAppId(@NonNull final String appId){ + sdlManager.appId = appId; + return this; + } + + /** + * Sets the Application Name + * @param appName String that will be associated as the app's name + */ + public Builder setAppName(@NonNull final String appName){ + sdlManager.appName = appName; + return this; + } + + /** + * Sets the Short Application Name + * @param shortAppName a shorter representation of the app's name for smaller displays + */ + public Builder setShortAppName(final String shortAppName) { + sdlManager.shortAppName = shortAppName; + return this; + } + + /** + * Sets the minimum protocol version that will be permitted to connect. + * If the protocol version of the head unit connected is below this version, + * the app will disconnect with an EndService protocol message and will not register. + * @param minimumProtocolVersion the minimum Protocol spec version that should be accepted + */ + public Builder setMinimumProtocolVersion(final Version minimumProtocolVersion) { + sdlManager.minimumProtocolVersion = minimumProtocolVersion; + return this; + } + + /** + * The minimum RPC version that will be permitted to connect. + * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. + * @param minimumRPCVersion the minimum RPC spec version that should be accepted + */ + public Builder setMinimumRPCVersion(final Version minimumRPCVersion) { + sdlManager.minimumRPCVersion = minimumRPCVersion; + return this; + } + + /** + * Sets the Language of the App + * @param hmiLanguage the desired language to be used on the display/HMI of the connected module + */ + public Builder setLanguage(final Language hmiLanguage){ + sdlManager.hmiLanguage = hmiLanguage; + return this; + } + + /** + * Sets the TemplateColorScheme for daytime + * @param dayColorScheme color scheme that will be used (if supported) when the display is in a "Day Mode" or + * similar. Should comprise of colors that contrast well during the day under sunlight. + */ + public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){ + sdlManager.dayColorScheme = dayColorScheme; + return this; + } + + /** + * Sets the TemplateColorScheme for nighttime + * @param nightColorScheme color scheme that will be used (if supported) when the display is in a "Night Mode" + * or similar. Should comprise of colors that contrast well during the night and are not + * brighter than average. + */ + public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){ + sdlManager.nightColorScheme = nightColorScheme; + return this; + } + + /** + * Sets the icon for the app on head unit / In-Vehicle-Infotainment system
+ * @param sdlArtwork the icon that will be used to represent this application on the connected module + */ + public Builder setAppIcon(final SdlArtwork sdlArtwork){ + sdlManager.appIcon = sdlArtwork; + return this; + } + + /** + * Sets the vector of AppHMIType
+ * Note: This should be an ordered list from most -> least relevant + * @param hmiTypes HMI types that represent this application. For example, if the app is a music player, the + * MEDIA HMIType should be included. + */ + public Builder setAppTypes(final Vector hmiTypes){ + + sdlManager.hmiTypes = hmiTypes; + + if (hmiTypes != null) { + sdlManager.isMediaApp = hmiTypes.contains(AppHMIType.MEDIA); + } + + return this; + } + + /** + * Sets the FileManagerConfig for the session.
+ * Note: If not set, the default configuration value of 1 will be set for + * artworkRetryCount and fileRetryCount in FileManagerConfig + * @param fileManagerConfig - configuration options + */ + public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){ + sdlManager.fileManagerConfig = fileManagerConfig; + return this; + } + + /** + * Sets the voice recognition synonyms that can be used to identify this application. + * @param vrSynonyms a vector of Strings that can be associated with this app. For example the app's name should + * be included as well as any phonetic spellings of the app name that might help the on-board + * VR system associated a users spoken word with the supplied synonyms. + */ + public Builder setVrSynonyms(final Vector vrSynonyms) { + sdlManager.vrSynonyms = vrSynonyms; + return this; + } + + /** + * Sets the Text-To-Speech Name of the application. These TTSChunks might be used by the module as an audio + * representation of the app's name. + * @param ttsChunks the TTS chunks that can represent this app's name + */ + public Builder setTtsName(final Vector ttsChunks) { + sdlManager.ttsChunks = ttsChunks; + return this; + } + + /** + * This Object type may change with the transport refactor + * Sets the BaseTransportConfig + * @param transport the type of transport that should be used for this SdlManager instance. + */ + public Builder setTransportType(@NonNull BaseTransportConfig transport){ + sdlManager.transport = transport; + return this; + } + + /** + * Sets the Security libraries + * @param secList The list of security class(es) + */ + @Deprecated + public Builder setSdlSecurity(List> secList) { + sdlManager.sdlSecList = secList; + return this; + } + + /** + * Sets the security libraries and a callback to notify caller when there is update to encryption service + * @param secList The list of security class(es) + * @param listener The callback object + */ + public Builder setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { + sdlManager.sdlSecList = secList; + sdlManager.serviceEncryptionListener = listener; + return this; + } + + /** + * Set the SdlManager Listener + * @param listener the listener + */ + public Builder setManagerListener(@NonNull final SdlManagerListener listener){ + sdlManager.managerListener = listener; + return this; + } + + /** + * Set RPCNotification listeners. SdlManager will preload these listeners before any RPCs are sent/received. + * @param listeners a map of listeners that will be called when a notification is received. + * Key represents the FunctionID of the notification and value represents the listener + */ + public Builder setRPCNotificationListeners(Map listeners){ + sdlManager.onRPCNotificationListeners = listeners; + return this; + } + + public SdlManager build() { + + if (sdlManager.appName == null) { + throw new IllegalArgumentException("You must specify an app name by calling setAppName"); + } + + if (sdlManager.appId == null) { + throw new IllegalArgumentException("You must specify an app ID by calling setAppId"); + } + + if (sdlManager.managerListener == null) { + throw new IllegalArgumentException("You must set a SdlManagerListener object"); + } + + if (sdlManager.hmiTypes == null) { + Vector hmiTypesDefault = new Vector<>(); + hmiTypesDefault.add(AppHMIType.DEFAULT); + sdlManager.hmiTypes = hmiTypesDefault; + sdlManager.isMediaApp = false; + } + if(sdlManager.fileManagerConfig == null){ + //if FileManagerConfig is not set use default + sdlManager.fileManagerConfig = new FileManagerConfig(); + } + + if (sdlManager.hmiLanguage == null){ + sdlManager.hmiLanguage = Language.EN_US; + } + + if (sdlManager.minimumProtocolVersion == null){ + sdlManager.minimumProtocolVersion = new Version("1.0.0"); + } + + if (sdlManager.minimumRPCVersion == null){ + sdlManager.minimumRPCVersion = new Version("1.0.0"); + } + + sdlManager.transitionToState(BaseSubManager.SETTING_UP); + + return sdlManager; + } + } + + /** + * Start a secured RPC service + */ + public void startRPCEncryption() { + if (lifecycleManager != null) { + lifecycleManager.startRPCEncryption(); + } + } } diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index 690c2fe71..53843c1bd 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -36,45 +36,11 @@ import android.support.annotation.NonNull; import android.util.Log; import com.smartdevicelink.managers.file.FileManager; -import com.smartdevicelink.managers.file.FileManagerConfig; -import com.smartdevicelink.managers.file.filetypes.SdlArtwork; -import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; -import com.smartdevicelink.managers.lifecycle.LifecycleManager; import com.smartdevicelink.managers.permission.PermissionManager; import com.smartdevicelink.managers.screen.ScreenManager; -import com.smartdevicelink.protocol.enums.FunctionID; -import com.smartdevicelink.protocol.enums.SessionType; -import com.smartdevicelink.proxy.RPCMessage; -import com.smartdevicelink.proxy.RPCRequest; -import com.smartdevicelink.proxy.RPCResponse; -import com.smartdevicelink.proxy.SystemCapabilityManager; -import com.smartdevicelink.proxy.interfaces.ISdl; -import com.smartdevicelink.proxy.rpc.ChangeRegistration; -import com.smartdevicelink.proxy.rpc.OnHMIStatus; -import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; -import com.smartdevicelink.proxy.rpc.SetAppIcon; -import com.smartdevicelink.proxy.rpc.TTSChunk; -import com.smartdevicelink.proxy.rpc.TemplateColorScheme; -import com.smartdevicelink.proxy.rpc.enums.AppHMIType; -import com.smartdevicelink.proxy.rpc.enums.Language; -import com.smartdevicelink.proxy.rpc.enums.Result; import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; -import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; -import com.smartdevicelink.security.SdlSecurityBase; -import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.util.DebugTool; -import com.smartdevicelink.util.Version; - -import org.json.JSONException; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Vector; /** @@ -89,742 +55,138 @@ import java.util.Vector; * 3. Sending Requests
* 4. Helper methods */ -public class SdlManager extends BaseSdlManager{ - - private static final String TAG = "SdlManager"; - - private SdlArtwork appIcon; - private SdlManagerListener managerListener; - private List> sdlSecList; - private ServiceEncryptionListener serviceEncryptionListener; - private FileManagerConfig fileManagerConfig; - - // Managers - private LifecycleManager lifecycleManager; - private PermissionManager permissionManager; - private FileManager fileManager; - private ScreenManager screenManager; - - - // INTERNAL INTERFACE - /** - * This is from the LifeCycleManager directly. In the future if there is a reason to be a man in the middle - * the SdlManager could create it's own, however right now it was only a duplication of logic tied to the LCM. - */ - private ISdl _internalInterface; - - - // Initialize proxyBridge with anonymous lifecycleListener - private final LifecycleManager.LifecycleListener lifecycleListener = new LifecycleManager.LifecycleListener() { - boolean initStarted = false; - @Override - public void onProxyConnected(LifecycleManager lifeCycleManager) { - Log.i(TAG,"Proxy is connected. Now initializing."); - synchronized (this){ - if(!initStarted){ - changeRegistrationRetry = 0; - checkLifecycleConfiguration(); - initialize(); - initStarted = true; - } - } - } - @Override - public void onServiceStarted(SessionType sessionType){ - - } - - @Override - public void onServiceEnded(SessionType sessionType){ - - } - - @Override - public void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason) { - Log.i(TAG,"Proxy is closed."); - if(managerListener != null){ - managerListener.onDestroy(SdlManager.this); - } - - } - - - @Override - public void onError(LifecycleManager lifeCycleManager, String info, Exception e) { - - } - }; - - // Sub manager listener - private final CompletionListener subManagerListener = new CompletionListener() { - @Override - public synchronized void onComplete(boolean success) { - if(!success){ - Log.e(TAG, "Sub manager failed to initialize"); - } - checkState(); - } - }; - - @Override - void checkState() { - if (permissionManager != null && fileManager != null && screenManager != null ){ - if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.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){ - 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) { - DebugTool.logInfo("SETTING UP sdl manager, some sub managers are still setting up"); - transitionToState(BaseSubManager.SETTING_UP); - // No need to notify developer here! - } else { - Log.w(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); - transitionToState(BaseSubManager.LIMITED); - handleQueuedNotifications(); - notifyDevListener(null); - onReady(); - } - } else { - // We should never be here, but somehow one of the sub-sub managers is null - String info = "ERROR one of the sdl sub managers is null"; - Log.e(TAG, info); - transitionToState(BaseSubManager.ERROR); - notifyDevListener(info); - } - } - - private void notifyDevListener(String info) { - if (managerListener != null) { - if (getState() == BaseSubManager.ERROR){ - managerListener.onError(this, info, null); - } else { - managerListener.onStart(this); - } - } - } - - private void onReady(){ - // Set the app icon - if (SdlManager.this.appIcon != null && SdlManager.this.appIcon.getName() != null) { - if (fileManager != null && fileManager.getState() == BaseSubManager.READY && !fileManager.hasUploadedFile(SdlManager.this.appIcon)) { - fileManager.uploadArtwork(SdlManager.this.appIcon, new CompletionListener() { - @Override - public void onComplete(boolean success) { - if (success) { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - }); - } else { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - } - - @Override - protected void checkLifecycleConfiguration() { - final Language actualLanguage = lifecycleManager.getRegisterAppInterfaceResponse().getLanguage(); - - if (actualLanguage != null && !actualLanguage.equals(hmiLanguage)) { - - final LifecycleConfigurationUpdate lcu = managerListener.managerShouldUpdateLifecycle(actualLanguage); - - if (lcu != null) { - ChangeRegistration changeRegistration = new ChangeRegistration(actualLanguage, actualLanguage); - changeRegistration.setAppName(lcu.getAppName()); - changeRegistration.setNgnMediaScreenAppName(lcu.getShortAppName()); - changeRegistration.setTtsName(lcu.getTtsName()); - changeRegistration.setVrSynonyms(lcu.getVoiceRecognitionCommandNames()); - changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()) { - // go through and change sdlManager properties that were changed via the LCU update - hmiLanguage = actualLanguage; - - if (lcu.getAppName() != null) { - appName = lcu.getAppName(); - } - - if (lcu.getShortAppName() != null) { - shortAppName = lcu.getShortAppName(); - } - - if (lcu.getTtsName() != null) { - ttsChunks = lcu.getTtsName(); - } - - if (lcu.getVoiceRecognitionCommandNames() != null) { - vrSynonyms = lcu.getVoiceRecognitionCommandNames(); - } - } - try { - Log.v(TAG, response.serializeJSON().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - Log.e(TAG, "Change Registration onError: " + resultCode + " | Info: " + info); - } - }); - _internalInterface.sendRPC(changeRegistration); - } - } - } - - @Override - protected void initialize(){ - // Instantiate sub managers - this.permissionManager = new PermissionManager(_internalInterface); - this.fileManager = new FileManager(_internalInterface, fileManagerConfig); - this.screenManager = new ScreenManager(_internalInterface, this.fileManager); - - // Start sub managers - this.permissionManager.start(subManagerListener); - this.fileManager.start(subManagerListener); - this.screenManager.start(subManagerListener); - } - - @Override - public void dispose() { - if (this.permissionManager != null) { - this.permissionManager.dispose(); - } - - if (this.fileManager != null) { - this.fileManager.dispose(); - } - - if (this.screenManager != null) { - this.screenManager.dispose(); - } - - if (this.lifecycleManager != null) { - this.lifecycleManager.stop(); - } - - if(managerListener != null){ - managerListener.onDestroy(this); - managerListener = null; - } - - transitionToState(BaseSubManager.SHUTDOWN); - } - - - // MANAGER GETTERS - /** - * Gets the PermissionManager.
- * Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a PermissionManager object - */ - public PermissionManager getPermissionManager() { - if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG,"PermissionManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return permissionManager; - } - - /** - * Gets the FileManager.
- * Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a FileManager object - */ - public FileManager getFileManager() { - if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "FileManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return fileManager; - } - - /** - * Gets the ScreenManager.
- * Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a ScreenManager object - */ - public ScreenManager getScreenManager() { - if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "ScreenManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return screenManager; - } - - /** - * Gets the SystemCapabilityManager.
- * Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a SystemCapabilityManager object - */ - public SystemCapabilityManager getSystemCapabilityManager(){ - return lifecycleManager.getSystemCapabilityManager(this); - } - - /** - * Method to retrieve the RegisterAppInterface Response message that was sent back from the - * module. It contains various attributes about the connected module and can be used to adapt - * to different module types and their supported features. - * - * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet - * registered with the module. - */ - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ - if(lifecycleManager != null){ - return lifecycleManager.getRegisterAppInterfaceResponse(); - } - return null; - } - - /** - * Get the current OnHMIStatus - * @return OnHMIStatus object represents the current OnHMIStatus - */ - @Override - public OnHMIStatus getCurrentHMIStatus(){ - if(this.lifecycleManager !=null ){ - return lifecycleManager.getCurrentHMIStatus(); - } - return null; - } - - // PROTECTED GETTERS - - protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } - - /** - * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC - * service from the module. For example, this should be used to login to a user account. - * @return the string representation of the auth token - */ - @Override - public String getAuthToken(){ - return this.lifecycleManager.getAuthToken(); - } - - // SENDING REQUESTS - - /** - * Send RPC Message
- * @param message RPCMessage - */ - @Override - public void sendRPC(RPCMessage message) { - _internalInterface.sendRPC(message); - } - - /** - * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests asynchronously, use sendRequests
- * - * NOTE: This will override any listeners on individual RPCs
- * - * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener){ - - List rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - _internalInterface.sendSequentialRPCs(rpcRequestList, listener); - } - } - - /** - * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests synchronously, use sendSequentialRPCs
- * - * NOTE: This will override any listeners on individual RPCs
- * - * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendRPCs(List rpcs, final OnMultipleRequestListener listener) { - - List rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - _internalInterface.sendRequests(rpcRequestList,listener); - } - } - - /** - * Add an OnRPCNotificationListener - * @param listener listener that will be called when a notification is received - */ - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - _internalInterface.addOnRPCNotificationListener(notificationId,listener); - } - - /** - * Remove an OnRPCNotificationListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - _internalInterface.removeOnRPCNotificationListener(notificationId, listener); - } - - /** - * Add an OnRPCRequestListener - * @param listener listener that will be called when a request is received - */ - @Override - public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - _internalInterface.addOnRPCRequestListener(requestId,listener); - } - - /** - * Remove an OnRPCRequestListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - _internalInterface.removeOnRPCRequestListener(requestId, listener); - } - - // LIFECYCLE / OTHER - - // STARTUP - - /** - * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up - */ - @SuppressWarnings("unchecked") - @Override - public void start(){ - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - dispose(); - } - }); - - Log.i(TAG, "start"); - if (lifecycleManager == null) { - if (transport != null - && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { - //Do the thing - - LifecycleManager.AppConfig appConfig = new LifecycleManager.AppConfig(); - appConfig.setAppName(appName); - //short app name - appConfig.setMediaApp(isMediaApp); - appConfig.setHmiDisplayLanguageDesired(hmiLanguage); - appConfig.setLanguageDesired(hmiLanguage); - appConfig.setAppType(hmiTypes); - appConfig.setVrSynonyms(vrSynonyms); - appConfig.setTtsName(ttsChunks); - appConfig.setDayColorScheme(dayColorScheme); - appConfig.setNightColorScheme(nightColorScheme); - appConfig.setAppID(appId); - appConfig.setMinimumProtocolVersion(minimumProtocolVersion); - appConfig.setMinimumRPCVersion(minimumRPCVersion); - - lifecycleManager = new LifecycleManager(appConfig, transport, lifecycleListener); - _internalInterface = lifecycleManager.getInternalInterface(SdlManager.this); - - if (sdlSecList != null && !sdlSecList.isEmpty()) { - lifecycleManager.setSdlSecurity(sdlSecList, serviceEncryptionListener); - } - - //Setup the notification queue - initNotificationQueue(); - - lifecycleManager.start(); - - - }else{ - throw new RuntimeException("No transport provided"); - } - } - } - - - // BUILDER - public static class Builder { - SdlManager sdlManager; - - /** - * Builder for the SdlManager. Parameters in the constructor are required. - * @param appId the app's ID - * @param appName the app's name - * @param listener a SdlManagerListener object - */ - public Builder(@NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ - sdlManager = new SdlManager(); - setAppId(appId); - setAppName(appName); - setManagerListener(listener); - } - - /** - * Sets the App ID - * @param appId String representation of the App ID retreived from the SDL Developer Portal - */ - public Builder setAppId(@NonNull final String appId){ - sdlManager.appId = appId; - return this; - } - - /** - * Sets the Application Name - * @param appName String that will be associated as the app's name - */ - public Builder setAppName(@NonNull final String appName){ - sdlManager.appName = appName; - return this; - } - - /** - * Sets the Short Application Name - * @param shortAppName a shorter representation of the app's name for smaller displays - */ - public Builder setShortAppName(final String shortAppName) { - sdlManager.shortAppName = shortAppName; - return this; - } - - /** - * Sets the minimum protocol version that will be permitted to connect. - * If the protocol version of the head unit connected is below this version, - * the app will disconnect with an EndService protocol message and will not register. - * @param minimumProtocolVersion the minimum Protocol spec version that should be accepted - */ - public Builder setMinimumProtocolVersion(final Version minimumProtocolVersion) { - sdlManager.minimumProtocolVersion = minimumProtocolVersion; - return this; - } - - /** - * The minimum RPC version that will be permitted to connect. - * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. - * @param minimumRPCVersion the minimum RPC spec version that should be accepted - */ - public Builder setMinimumRPCVersion(final Version minimumRPCVersion) { - sdlManager.minimumRPCVersion = minimumRPCVersion; - return this; - } - - /** - * Sets the Language of the App - * @param hmiLanguage the desired language to be used on the display/HMI of the connected module - */ - public Builder setLanguage(final Language hmiLanguage){ - sdlManager.hmiLanguage = hmiLanguage; - return this; - } - - /** - * Sets the TemplateColorScheme for daytime - * @param dayColorScheme color scheme that will be used (if supported) when the display is in a "Day Mode" or - * similar. Should comprise of colors that contrast well during the day under sunlight. - */ - public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){ - sdlManager.dayColorScheme = dayColorScheme; - return this; - } - - /** - * Sets the TemplateColorScheme for nighttime - * @param nightColorScheme color scheme that will be used (if supported) when the display is in a "Night Mode" - * or similar. Should comprise of colors that contrast well during the night and are not - * brighter than average. - */ - public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){ - sdlManager.nightColorScheme = nightColorScheme; - return this; - } - - /** - * Sets the icon for the app on head unit / In-Vehicle-Infotainment system
- * @param sdlArtwork the icon that will be used to represent this application on the connected module - */ - public Builder setAppIcon(final SdlArtwork sdlArtwork){ - sdlManager.appIcon = sdlArtwork; - return this; - } - - /** - * Sets the vector of AppHMIType
- * Note: This should be an ordered list from most -> least relevant - * @param hmiTypes HMI types that represent this application. For example, if the app is a music player, the - * MEDIA HMIType should be included. - */ - public Builder setAppTypes(final Vector hmiTypes){ - - sdlManager.hmiTypes = hmiTypes; - - if (hmiTypes != null) { - sdlManager.isMediaApp = hmiTypes.contains(AppHMIType.MEDIA); - } - - return this; - } - - /** - * Sets the FileManagerConfig for the session.
- * Note: If not set, the default configuration value of 1 will be set for - * artworkRetryCount and fileRetryCount in FileManagerConfig - * @param fileManagerConfig - configuration options - */ - public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){ - sdlManager.fileManagerConfig = fileManagerConfig; - return this; - } - - /** - * Sets the voice recognition synonyms that can be used to identify this application. - * @param vrSynonyms a vector of Strings that can be associated with this app. For example the app's name should - * be included as well as any phonetic spellings of the app name that might help the on-board - * VR system associated a users spoken word with the supplied synonyms. - */ - public Builder setVrSynonyms(final Vector vrSynonyms) { - sdlManager.vrSynonyms = vrSynonyms; - return this; - } - - /** - * Sets the Text-To-Speech Name of the application. These TTSChunks might be used by the module as an audio - * representation of the app's name. - * @param ttsChunks the TTS chunks that can represent this app's name - */ - public Builder setTtsName(final Vector ttsChunks) { - sdlManager.ttsChunks = ttsChunks; - return this; - } - - /** - * This Object type may change with the transport refactor - * Sets the BaseTransportConfig - * @param transport the type of transport that should be used for this SdlManager instance. - */ - public Builder setTransportType(BaseTransportConfig transport){ - sdlManager.transport = transport; - return this; - } - - /** - * Sets the Security libraries - * @param secList The list of security class(es) - */ - @Deprecated - public Builder setSdlSecurity(List> secList) { - sdlManager.sdlSecList = secList; - return this; - } - - /** - * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) - * @param listener The callback object - */ - public Builder setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { - sdlManager.sdlSecList = secList; - sdlManager.serviceEncryptionListener = listener; - return this; - } - - /** - * Set the SdlManager Listener - * @param listener the listener - */ - public Builder setManagerListener(@NonNull final SdlManagerListener listener){ - sdlManager.managerListener = listener; - return this; - } - - /** - * Set RPCNotification listeners. SdlManager will preload these listeners before any RPCs are sent/received. - * @param listeners a map of listeners that will be called when a notification is received. - * Key represents the FunctionID of the notification and value represents the listener - */ - public Builder setRPCNotificationListeners(Map listeners){ - sdlManager.onRPCNotificationListeners = listeners; - return this; - } - - public SdlManager build() { - - if (sdlManager.appName == null) { - throw new IllegalArgumentException("You must specify an app name by calling setAppName"); - } - - if (sdlManager.appId == null) { - throw new IllegalArgumentException("You must specify an app ID by calling setAppId"); - } - - if (sdlManager.managerListener == null) { - throw new IllegalArgumentException("You must set a SdlManagerListener object"); - } - - if (sdlManager.hmiTypes == null) { - Vector hmiTypesDefault = new Vector<>(); - hmiTypesDefault.add(AppHMIType.DEFAULT); - sdlManager.hmiTypes = hmiTypesDefault; - sdlManager.isMediaApp = false; - } - if(sdlManager.fileManagerConfig == null){ - //if FileManagerConfig is not set use default - sdlManager.fileManagerConfig = new FileManagerConfig(); - } - - if (sdlManager.hmiLanguage == null){ - sdlManager.hmiLanguage = Language.EN_US; - } - - if (sdlManager.minimumProtocolVersion == null){ - sdlManager.minimumProtocolVersion = new Version("1.0.0"); - } - - if (sdlManager.minimumRPCVersion == null){ - sdlManager.minimumRPCVersion = new Version("1.0.0"); - } - - sdlManager.transitionToState(BaseSubManager.SETTING_UP); - - return sdlManager; - } - } - - /** - * Start a secured RPC service - */ - public void startRPCEncryption() { - if (lifecycleManager != null) { - lifecycleManager.startRPCEncryption(); - } - } +public class SdlManager extends BaseSdlManager { + + + @Override + void onProxyClosed(SdlDisconnectedReason reason) { + Log.i(TAG,"Proxy is closed."); + if(managerListener != null){ + managerListener.onDestroy(SdlManager.this); + } + } + + @Override + void checkState() { + if (permissionManager != null && fileManager != null && screenManager != null ){ + if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.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){ + 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) { + DebugTool.logInfo("SETTING UP sdl manager, some sub managers are still setting up"); + transitionToState(BaseSubManager.SETTING_UP); + // No need to notify developer here! + } else { + Log.w(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); + transitionToState(BaseSubManager.LIMITED); + handleQueuedNotifications(); + notifyDevListener(null); + onReady(); + } + } else { + // We should never be here, but somehow one of the sub-sub managers is null + String info = "ERROR one of the sdl sub managers is null"; + Log.e(TAG, info); + transitionToState(BaseSubManager.ERROR); + notifyDevListener(info); + } + } + + private void notifyDevListener(String info) { + if (managerListener != null) { + if (getState() == BaseSubManager.ERROR){ + managerListener.onError((SdlManager)this, info, null); + } else { + managerListener.onStart((SdlManager) this); + } + } + } + + @Override + void retryChangeRegistration() { + // Do nothing + } + + @Override + protected void initialize(){ + // Instantiate sub managers + this.permissionManager = new PermissionManager(_internalInterface); + this.fileManager = new FileManager(_internalInterface, fileManagerConfig); + this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + + // Start sub managers + this.permissionManager.start(subManagerListener); + this.fileManager.start(subManagerListener); + this.screenManager.start(subManagerListener); + } + + @Override + public void dispose() { + if (this.permissionManager != null) { + this.permissionManager.dispose(); + } + + if (this.fileManager != null) { + this.fileManager.dispose(); + } + + if (this.screenManager != null) { + this.screenManager.dispose(); + } + + if (this.lifecycleManager != null) { + this.lifecycleManager.stop(); + } + + if(managerListener != null){ + managerListener.onDestroy((SdlManager)this); + managerListener = null; + } + + transitionToState(BaseSubManager.SHUTDOWN); + } + + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @SuppressWarnings("unchecked") + public void start() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + dispose(); + } + }); + + Log.i(TAG, "start"); + if (lifecycleManager == null) { + if (transport != null + && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { + super.start(); + } else { + throw new RuntimeException("No transport provided"); + } + } + } + + // BUILDER + public static class Builder extends BaseSdlManager.Builder { + /** + * Builder for the SdlManager. Parameters in the constructor are required. + * @param appId the app's ID + * @param appName the app's name + * @param listener a SdlManagerListener object + */ + public Builder(@NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ + super(appId, appName, listener); + } + } } -- cgit v1.2.1 From 2e23c196821cd99acd2a3d9a7d61cb14770e4705 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 29 May 2020 13:44:08 -0400 Subject: Update code formatting --- .../com/smartdevicelink/managers/SdlManager.java | 155 +++++++++------------ .../managers/lifecycle/LifecycleManager.java | 17 +-- .../smartdevicelink/managers/BaseSdlManager.java | 76 ++++------ .../managers/lifecycle/BaseLifecycleManager.java | 46 +++--- .../com/smartdevicelink/managers/SdlManager.java | 76 +++++----- .../managers/lifecycle/LifecycleManager.java | 17 +-- 6 files changed, 154 insertions(+), 233 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 6be06f673..4b4cbddef 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 @@ -74,23 +74,79 @@ public class SdlManager extends BaseSdlManager{ private Context context; private LockScreenConfig lockScreenConfig; - // Managers private LockScreenManager lockScreenManager; private VideoStreamManager videoStreamManager; private AudioStreamManager audioStreamManager; + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @Override + public void start(){ + if (lifecycleManager == null) { + if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ + //Do the thing + MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); + final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); + multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { + @Override + public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { + + //Pass to submanagers that need it + if(videoStreamManager != null){ + videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + + if(audioStreamManager != null){ + audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + //If the developer supplied a listener to start, it is time to call that + if(devListener != null){ + devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); + } + } + }); + + //If the requires audio support has not been set, it should be set to true if the + //app is a media app, and false otherwise + if(multiplexTransportConfig.requiresAudioSupport() == null){ + multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); + } + } + + super.start(); + } + } @Override - void onProxyClosed(SdlDisconnectedReason reason) { - Log.i(TAG,"Proxy is closed."); - if(managerListener != null){ - managerListener.onDestroy(); + protected void initialize(){ + // Instantiate sub managers + this.permissionManager = new PermissionManager(_internalInterface); + this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); + if (lockScreenConfig.isEnabled()) { + this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); + } + this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + if(getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)){ + this.videoStreamManager = new VideoStreamManager(_internalInterface); + } else { + this.videoStreamManager = null; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) ) { + this.audioStreamManager = new AudioStreamManager(_internalInterface, context); + } else { + this.audioStreamManager = null; } - if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ - dispose(); + // Start sub managers + this.permissionManager.start(subManagerListener); + this.fileManager.start(subManagerListener); + if (lockScreenConfig.isEnabled()){ + this.lockScreenManager.start(subManagerListener); } + this.screenManager.start(subManagerListener); } @Override @@ -153,33 +209,15 @@ public class SdlManager extends BaseSdlManager{ } @Override - protected void initialize(){ - // Instantiate sub managers - this.permissionManager = new PermissionManager(_internalInterface); - this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); - if (lockScreenConfig.isEnabled()) { - this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); - } - this.screenManager = new ScreenManager(_internalInterface, this.fileManager); - if(getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)){ - this.videoStreamManager = new VideoStreamManager(_internalInterface); - } else { - this.videoStreamManager = null; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) ) { - this.audioStreamManager = new AudioStreamManager(_internalInterface, context); - } else { - this.audioStreamManager = null; + void onProxyClosed(SdlDisconnectedReason reason) { + Log.i(TAG,"Proxy is closed."); + if(managerListener != null){ + managerListener.onDestroy(); } - // Start sub managers - this.permissionManager.start(subManagerListener); - this.fileManager.start(subManagerListener); - if (lockScreenConfig.isEnabled()){ - this.lockScreenManager.start(subManagerListener); + if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ + dispose(); } - this.screenManager.start(subManagerListener); } /** Dispose SdlManager and clean its resources @@ -226,8 +264,6 @@ public class SdlManager extends BaseSdlManager{ } // MANAGER GETTERS - - /** * Gets the VideoStreamManager.
* The VideoStreamManager returned will only be not null if the registered app type is @@ -255,7 +291,6 @@ public class SdlManager extends BaseSdlManager{ return audioStreamManager; } - /** * Gets the LockScreenManager.
* Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. @@ -269,59 +304,9 @@ public class SdlManager extends BaseSdlManager{ return lockScreenManager; } - - // PROTECTED GETTERS - protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; } - - - // LIFECYCLE / OTHER - - // STARTUP - - /** - * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up - */ - @Override - public void start(){ - if (lifecycleManager == null) { - if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ - //Do the thing - MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); - final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); - multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { - @Override - public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { - - //Pass to submanagers that need it - if(videoStreamManager != null){ - videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - - if(audioStreamManager != null){ - audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - //If the developer supplied a listener to start, it is time to call that - if(devListener != null){ - devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); - } - } - }); - - //If the requires audio support has not been set, it should be set to true if the - //app is a media app, and false otherwise - if(multiplexTransportConfig.requiresAudioSupport() == null){ - multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); - } - } - - super.start(); - } - } - - // BUILDER public static class Builder extends BaseSdlManager.Builder{ /** @@ -358,7 +343,6 @@ public class SdlManager extends BaseSdlManager{ return this; } - /** * Sets the Context * @param context @@ -368,7 +352,6 @@ public class SdlManager extends BaseSdlManager{ return this; } - /** * Build SdlManager ang get it ready to be started * Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed. 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 71f3adc8f..dca8d0253 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 @@ -36,14 +36,11 @@ import android.support.annotation.RestrictTo; import com.smartdevicelink.SdlConnection.SdlSession; import com.smartdevicelink.SdlConnection.SdlSession2; -import com.smartdevicelink.proxy.SystemCapabilityManager; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.TCPTransportConfig; import com.smartdevicelink.transport.enums.TransportType; -import java.util.HashMap; - /** * 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. @@ -52,17 +49,7 @@ import java.util.HashMap; @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - - this.lifecycleListener = listener; - - this.rpcListeners = new HashMap<>(); - this.rpcResponseListeners = new HashMap<>(); - this.rpcNotificationListeners = new HashMap<>(); - this.rpcRequestListeners = new HashMap<>(); - - this.appConfig = appConfig; - this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); - this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); + super(appConfig, config, listener); if (config != null && config.getTransportType().equals(TransportType.MULTIPLEX)) { this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) config); @@ -71,7 +58,5 @@ public class LifecycleManager extends BaseLifecycleManager { }else { this.session = SdlSession.createSession((byte)getProtocolVersion().getMajor(),sdlConnectionListener, config); } - - this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); } } diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index cc5494ff9..c09c0560c 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -110,7 +110,6 @@ abstract class BaseSdlManager { FileManager fileManager; ScreenManager screenManager; - // INTERNAL INTERFACE /** * This is from the LifeCycleManager directly. In the future if there is a reason to be a man in the middle @@ -118,7 +117,6 @@ abstract class BaseSdlManager { */ ISdl _internalInterface; - // Initialize with anonymous lifecycleListener final LifecycleManager.LifecycleListener lifecycleListener = new LifecycleManager.LifecycleListener() { boolean initStarted = false; @@ -149,7 +147,6 @@ abstract class BaseSdlManager { BaseSdlManager.this.onProxyClosed(reason); } - @Override public void onError(LifecycleManager lifeCycleManager, String info, Exception e) { @@ -167,30 +164,12 @@ abstract class BaseSdlManager { } }; - // PROTECTED GETTERS - protected String getAppName() { return appName; } - - protected String getAppId() { return appId; } - - protected String getShortAppName() { return shortAppName; } - - protected Version getMinimumProtocolVersion() { return minimumProtocolVersion; } - - protected Version getMinimumRPCVersion() { return minimumRPCVersion; } - - protected Language getHmiLanguage() { return hmiLanguage; } - - protected TemplateColorScheme getDayColorScheme() { return dayColorScheme; } - - protected TemplateColorScheme getNightColorScheme() { return nightColorScheme; } - - protected Vector getAppTypes() { return hmiTypes; } - - protected Vector getVrSynonyms() { return vrSynonyms; } - - protected Vector getTtsChunks() { return ttsChunks; } - - protected BaseTransportConfig getTransport() { return transport; } + // ABSTRACT METHODS + abstract void retryChangeRegistration(); + abstract void onProxyClosed(SdlDisconnectedReason reason); + abstract void checkState(); + abstract void initialize(); + public abstract void dispose(); protected void checkLifecycleConfiguration() { final Language actualLanguage = lifecycleManager.getRegisterAppInterfaceResponse().getLanguage(); @@ -321,14 +300,6 @@ abstract class BaseSdlManager { } } - abstract void retryChangeRegistration(); - abstract void onProxyClosed(SdlDisconnectedReason reason); - abstract void checkState(); - abstract void initialize(); - public abstract void dispose(); - - - /** * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up */ @@ -362,7 +333,6 @@ abstract class BaseSdlManager { lifecycleManager.start(); } - void onReady(){ // Set the app icon if (BaseSdlManager.this.appIcon != null && BaseSdlManager.this.appIcon.getName() != null) { @@ -383,11 +353,32 @@ abstract class BaseSdlManager { } } + // PROTECTED GETTERS + protected String getAppName() { return appName; } + protected String getAppId() { return appId; } + protected String getShortAppName() { return shortAppName; } + protected Version getMinimumProtocolVersion() { return minimumProtocolVersion; } + protected Version getMinimumRPCVersion() { return minimumRPCVersion; } + protected Language getHmiLanguage() { return hmiLanguage; } + + protected TemplateColorScheme getDayColorScheme() { return dayColorScheme; } + + protected TemplateColorScheme getNightColorScheme() { return nightColorScheme; } + + protected Vector getAppTypes() { return hmiTypes; } + + protected Vector getVrSynonyms() { return vrSynonyms; } + + protected Vector getTtsChunks() { return ttsChunks; } + + protected BaseTransportConfig getTransport() { return transport; } + + protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } // MANAGER GETTERS /** @@ -464,10 +455,6 @@ abstract class BaseSdlManager { return null; } - // PROTECTED GETTERS - - protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } - /** * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC * service from the module. For example, this should be used to login to a user account. @@ -499,7 +486,6 @@ abstract class BaseSdlManager { * @param listener listener for updates and completions */ public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener){ - List rpcRequestList = new ArrayList<>(); for (int i = 0; i < rpcs.size(); i++) { if (rpcs.get(i) instanceof RPCRequest){ @@ -524,7 +510,6 @@ abstract class BaseSdlManager { * @param listener listener for updates and completions */ public void sendRPCs(List rpcs, final OnMultipleRequestListener listener) { - List rpcRequestList = new ArrayList<>(); for (int i = 0; i < rpcs.size(); i++) { if (rpcs.get(i) instanceof RPCRequest){ @@ -569,10 +554,6 @@ abstract class BaseSdlManager { _internalInterface.removeOnRPCRequestListener(requestId, listener); } - // LIFECYCLE / OTHER - - - // BUILDER public static class Builder { SdlManager sdlManager; @@ -677,7 +658,6 @@ abstract class BaseSdlManager { * MEDIA HMIType should be included. */ public Builder setAppTypes(final Vector hmiTypes){ - sdlManager.hmiTypes = hmiTypes; if (hmiTypes != null) { @@ -770,7 +750,6 @@ abstract class BaseSdlManager { } public SdlManager build() { - if (sdlManager.appName == null) { throw new IllegalArgumentException("You must specify an app name by calling setAppName"); } @@ -820,5 +799,4 @@ abstract class BaseSdlManager { lifecycleManager.startRPCEncryption(); } } - } 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 241670bbe..3f7f6c73e 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -104,49 +104,51 @@ import java.util.concurrent.CopyOnWriteArrayList; abstract class BaseLifecycleManager { private static final String TAG = "Lifecycle Manager"; - public static final Version MAX_SUPPORTED_RPC_VERSION = new Version(6, 0, 0); // Protected Correlation IDs - private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, + private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; - // Sdl Synchronization Objects private static final Object RPC_LISTENER_LOCK = new Object(), ON_UPDATE_LISTENER_LOCK = new Object(), ON_REQUEST_LISTENER_LOCK = new Object(), ON_NOTIFICATION_LISTENER_LOCK = new Object(); - - SdlSession session; AppConfig appConfig; - - //protected Version protocolVersion = new Version(1,0,0); - protected Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; - - + Version rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; HashMap> rpcListeners; HashMap rpcResponseListeners; HashMap> rpcNotificationListeners; HashMap> rpcRequestListeners; - SystemCapabilityManager systemCapabilityManager; private EncryptionLifecycleManager encryptionLifecycleManager; - - protected RegisterAppInterfaceResponse raiResponse = null; - + RegisterAppInterfaceResponse raiResponse = null; private OnHMIStatus currentHMIStatus; - protected boolean firstTimeFull = true; - + boolean firstTimeFull = true; LifecycleListener lifecycleListener; - private List> _secList = null; private String authToken; Version minimumProtocolVersion; Version minimumRPCVersion; + BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + this.lifecycleListener = listener; + + this.rpcListeners = new HashMap<>(); + this.rpcResponseListeners = new HashMap<>(); + this.rpcNotificationListeners = new HashMap<>(); + this.rpcRequestListeners = new HashMap<>(); + + this.appConfig = appConfig; + this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); + this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); + + this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); + } + public void start(){ try { setupInternalRpcListeners(); @@ -154,7 +156,6 @@ abstract class BaseLifecycleManager { } catch (SdlException e) { e.printStackTrace(); } - } /** @@ -322,7 +323,6 @@ abstract class BaseLifecycleManager { return this.raiResponse; } - /** * Get the current OnHMIStatus * @return OnHMIStatus object represents the current OnHMIStatus @@ -353,7 +353,6 @@ abstract class BaseLifecycleManager { return null; } - /* ******************************************************************************************************* ********************************** INTERNAL - RPC LISTENERS !! START !! ********************************* *********************************************************************************************************/ @@ -367,7 +366,6 @@ abstract class BaseLifecycleManager { addRpcListener(FunctionID.UNREGISTER_APP_INTERFACE, rpcListener); } - private OnRPCListener rpcListener = new OnRPCListener() { @Override public void onReceived(RPCMessage message) { @@ -723,8 +721,6 @@ abstract class BaseLifecycleManager { **************************************** RPC LISTENERS !! END !! **************************************** *********************************************************************************************************/ - - private void sendRPCMessagePrivate(RPCMessage message){ try { //FIXME this is temporary until the next major release of the library where OK is removed @@ -757,7 +753,6 @@ abstract class BaseLifecycleManager { } } - message.format(rpcSpecVersion,true); byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor()); @@ -833,8 +828,6 @@ abstract class BaseLifecycleManager { } } - - /* ******************************************************************************************************* *************************************** ISdlConnectionListener START ************************************ *********************************************************************************************************/ @@ -1354,7 +1347,6 @@ abstract class BaseLifecycleManager { } } - /** * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old * OK button name. This should be removed during the next major release diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index 53843c1bd..a5e36b8b2 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -42,7 +42,6 @@ import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.util.DebugTool; - /** * SDLManager
* @@ -57,15 +56,42 @@ import com.smartdevicelink.util.DebugTool; */ public class SdlManager extends BaseSdlManager { + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @SuppressWarnings("unchecked") + public void start() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + dispose(); + } + }); - @Override - void onProxyClosed(SdlDisconnectedReason reason) { - Log.i(TAG,"Proxy is closed."); - if(managerListener != null){ - managerListener.onDestroy(SdlManager.this); + Log.i(TAG, "start"); + if (lifecycleManager == null) { + if (transport != null + && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { + super.start(); + } else { + throw new RuntimeException("No transport provided"); + } } } + @Override + protected void initialize(){ + // Instantiate sub managers + this.permissionManager = new PermissionManager(_internalInterface); + this.fileManager = new FileManager(_internalInterface, fileManagerConfig); + this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + + // Start sub managers + this.permissionManager.start(subManagerListener); + this.fileManager.start(subManagerListener); + this.screenManager.start(subManagerListener); + } + @Override void checkState() { if (permissionManager != null && fileManager != null && screenManager != null ){ @@ -116,16 +142,11 @@ public class SdlManager extends BaseSdlManager { } @Override - protected void initialize(){ - // Instantiate sub managers - this.permissionManager = new PermissionManager(_internalInterface); - this.fileManager = new FileManager(_internalInterface, fileManagerConfig); - this.screenManager = new ScreenManager(_internalInterface, this.fileManager); - - // Start sub managers - this.permissionManager.start(subManagerListener); - this.fileManager.start(subManagerListener); - this.screenManager.start(subManagerListener); + void onProxyClosed(SdlDisconnectedReason reason) { + Log.i(TAG,"Proxy is closed."); + if(managerListener != null){ + managerListener.onDestroy(SdlManager.this); + } } @Override @@ -154,29 +175,6 @@ public class SdlManager extends BaseSdlManager { transitionToState(BaseSubManager.SHUTDOWN); } - /** - * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up - */ - @SuppressWarnings("unchecked") - public void start() { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - dispose(); - } - }); - - Log.i(TAG, "start"); - if (lifecycleManager == null) { - if (transport != null - && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { - super.start(); - } else { - throw new RuntimeException("No transport provided"); - } - } - } - // BUILDER public static class Builder extends BaseSdlManager.Builder { /** diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index 0025f3368..e3c45516a 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -35,11 +35,8 @@ package com.smartdevicelink.managers.lifecycle; import android.support.annotation.RestrictTo; import com.smartdevicelink.SdlConnection.SdlSession; -import com.smartdevicelink.proxy.SystemCapabilityManager; import com.smartdevicelink.transport.BaseTransportConfig; -import java.util.HashMap; - /** * 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. @@ -47,19 +44,7 @@ import java.util.HashMap; @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - - this.lifecycleListener = listener; - - this.rpcListeners = new HashMap<>(); - this.rpcResponseListeners = new HashMap<>(); - this.rpcNotificationListeners = new HashMap<>(); - this.rpcRequestListeners = new HashMap<>(); - - this.appConfig = appConfig; - this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); - this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); + super(appConfig, config, listener); this.session = new SdlSession(sdlConnectionListener, config); - - this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); } } -- cgit v1.2.1 From 3917c85a6a7e90716ed6f68f0bb1653441fd2169 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Mon, 1 Jun 2020 16:19:47 -0400 Subject: Check NPE in onProxyClosed --- .../src/main/java/com/smartdevicelink/managers/SdlManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4b4cbddef..570058280 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 @@ -215,7 +215,7 @@ public class SdlManager extends BaseSdlManager{ managerListener.onDestroy(); } - if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ + if (reason == null || !reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ dispose(); } } -- cgit v1.2.1 From 18f803e4d2fb505c17a35b778a3837351533d98b Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Tue, 2 Jun 2020 10:22:43 -0400 Subject: Update SdlManager javadoc --- .../src/main/java/com/smartdevicelink/managers/SdlManager.java | 5 ++--- javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java | 2 +- 2 files changed, 3 insertions(+), 4 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 570058280..86697f0b4 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 @@ -272,8 +272,7 @@ public class SdlManager extends BaseSdlManager{ *

Note: VideoStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. * @return a VideoStreamManager object attached to this SdlManager instance */ - public @Nullable - VideoStreamManager getVideoStreamManager() { + public @Nullable VideoStreamManager getVideoStreamManager() { checkSdlManagerState(); return videoStreamManager; } @@ -345,7 +344,7 @@ public class SdlManager extends BaseSdlManager{ /** * Sets the Context - * @param context + * @param context the current context */ public Builder setContext(Context context){ sdlManager.context = context; diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index a5e36b8b2..82381a7ce 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -59,7 +59,7 @@ public class SdlManager extends BaseSdlManager { /** * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up */ - @SuppressWarnings("unchecked") + @Override public void start() { Runtime.getRuntime().addShutdownHook(new Thread() { @Override -- cgit v1.2.1 From 7e926f28f8f8a8f57a7559093c73a09b075b3d05 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Tue, 2 Jun 2020 15:29:03 -0400 Subject: Add NAV & PCM dupport to EncryptionLifecycleManager --- .../smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java | 3 +++ .../managers/lifecycle/BaseEncryptionLifecycleManager.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java index 1d5915bf4..99723b456 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java @@ -35,11 +35,14 @@ package com.smartdevicelink.managers.lifecycle; import android.support.annotation.NonNull; import com.smartdevicelink.managers.ServiceEncryptionListener; +import com.smartdevicelink.protocol.enums.SessionType; import com.smartdevicelink.proxy.interfaces.ISdl; class EncryptionLifecycleManager extends BaseEncryptionLifecycleManager { EncryptionLifecycleManager(@NonNull ISdl internalInterface, ServiceEncryptionListener listener) { super(internalInterface, listener); + internalInterface.addServiceListener(SessionType.NAV, securedServiceListener); + internalInterface.addServiceListener(SessionType.PCM, securedServiceListener); } } diff --git a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseEncryptionLifecycleManager.java b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseEncryptionLifecycleManager.java index 808f4b0cd..eca2ce239 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseEncryptionLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseEncryptionLifecycleManager.java @@ -57,6 +57,7 @@ abstract class BaseEncryptionLifecycleManager { private HMILevel currentHMILevel; private Set encryptionRequiredRPCs = new HashSet<>(); private boolean rpcSecuredServiceStarted; + ISdlServiceListener securedServiceListener; BaseEncryptionLifecycleManager(@NonNull ISdl isdl, ServiceEncryptionListener listener) { internalInterface = isdl; @@ -94,7 +95,7 @@ abstract class BaseEncryptionLifecycleManager { } }; - ISdlServiceListener securedServiceListener = new ISdlServiceListener() { + securedServiceListener = new ISdlServiceListener() { @Override public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { if(SessionType.RPC.equals(type)){ -- cgit v1.2.1 From 050ae26425751b3beaa0995f3724c22ebe05351f Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Tue, 2 Jun 2020 15:53:26 -0400 Subject: Add basic NAV & PCM support to BaseLifecycleManager --- .../managers/lifecycle/BaseLifecycleManager.java | 305 ++++++++++++++++++++- 1 file changed, 295 insertions(+), 10 deletions(-) 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 3f7f6c73e..0e62032b5 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -99,7 +99,11 @@ import com.smartdevicelink.util.Version; import java.util.HashMap; import java.util.List; import java.util.Vector; +import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledExecutorService; abstract class BaseLifecycleManager { @@ -134,6 +138,22 @@ abstract class BaseLifecycleManager { Version minimumProtocolVersion; Version minimumRPCVersion; + private static final int RESPONSE_WAIT_TIME = 2000; + private ISdlServiceListener navServiceListener; + private boolean navServiceStartResponseReceived = false; + private boolean navServiceStartResponse = false; + private List navServiceStartRejectedParams = null; + private boolean pcmServiceStartResponseReceived = false; + private boolean pcmServiceStartResponse = false; + private List pcmServiceStartRejectedParams = null; + private boolean navServiceEndResponseReceived = false; + private boolean navServiceEndResponse = false; + private boolean pcmServiceEndResponseReceived = false; + private boolean pcmServiceEndResponse = false; + private boolean rpcProtectedResponseReceived = false; + private boolean rpcProtectedStartResponse = false; + + BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ this.lifecycleListener = listener; @@ -897,7 +917,14 @@ abstract class BaseLifecycleManager { @Override public void onProtocolSessionStartedNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID, List rejectedParams) { - Log.w(TAG, "onProtocolSessionStartedNACKed " + sessionID); + Log.w(TAG, sessionType + " onProtocolSessionStartedNACKed " + sessionID + " RejectedParams: " + rejectedParams); + + if (sessionType.eq(SessionType.NAV)) { + NavServiceStartedNACK(rejectedParams); + } + else if (sessionType.eq(SessionType.PCM)) { + AudioServiceStartedNACK(rejectedParams); + } } @Override @@ -943,6 +970,10 @@ abstract class BaseLifecycleManager { } + } else if (sessionType.eq(SessionType.NAV)) { + NavServiceStarted(); + } else if (sessionType.eq(SessionType.PCM)) { + AudioServiceStarted(); } else { lifecycleListener.onServiceStarted(sessionType); } @@ -951,12 +982,22 @@ abstract class BaseLifecycleManager { @Override public void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID) { - + if (sessionType.eq(SessionType.NAV)) { + NavServiceEnded(); + } + else if (sessionType.eq(SessionType.PCM)) { + AudioServiceEnded(); + } } @Override public void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID) { - + if (sessionType.eq(SessionType.NAV)) { + NavServiceEndedNACK(); + } + else if (sessionType.eq(SessionType.PCM)) { + AudioServiceEndedNACK(); + } } @Override @@ -1014,13 +1055,16 @@ abstract class BaseLifecycleManager { @Override public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { - DebugTool.logWarning("startVideoService is not currently implemented"); + if(isConnected()){ + BaseLifecycleManager.this.startVideoService(encrypted,parameters); + } } @Override public void stopVideoService() { - DebugTool.logWarning("stopVideoService is not currently implemented"); - + if(isConnected()){ + BaseLifecycleManager.this.endVideoStream(); + } } @Override @@ -1036,13 +1080,16 @@ abstract class BaseLifecycleManager { @Override public void startAudioService(boolean encrypted) { - DebugTool.logWarning("startAudioService is not currently implemented"); - + if(isConnected()){ + BaseLifecycleManager.this.startService(SessionType.PCM, encrypted); + } } @Override public void stopAudioService() { - DebugTool.logWarning("stopAudioService is not currently implemented"); + if(isConnected()){ + BaseLifecycleManager.this.endAudioStream(); + } } @Override @@ -1054,7 +1101,6 @@ abstract class BaseLifecycleManager { @Override public void sendRPCRequest(RPCRequest message) { BaseLifecycleManager.this.sendRPCMessagePrivate(message); - } @Override @@ -1469,4 +1515,243 @@ abstract class BaseLifecycleManager { } } } + + + + + ///////////////////////////// + + /** + * Try to open a video service by using the video streaming parameters supplied. + *

+ * Only information from codecs, width and height are used during video format negotiation. + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. + * @return If the service is opened successfully, an instance of VideoStreamingParams is + * returned which contains accepted video format. If the service is opened with legacy + * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is + * returned. If the service was not opened then null is returned. + */ + private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return null; + } + if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) { + DebugTool.logWarning("Module doesn't support video streaming."); + return null; + } + if (parameters == null) { + DebugTool.logWarning("Video parameters were not supplied."); + return null; + } + + if (!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before + || (navServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one + session.setDesiredVideoParams(parameters); + + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + navServiceStartRejectedParams = null; + + session.startService(SessionType.NAV, session.getSessionId(), isEncrypted); + addNavListener(); + FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceStartResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + } + + if (navServiceStartResponse) { + if (getProtocolVersion() != null && getProtocolVersion().getMajor() < 5) { //Versions 1-4 do not support streaming parameter negotiations + session.setAcceptedVideoParams(parameters); + } + return session.getAcceptedVideoParams(); + } + + return null; + } + + private void addNavListener() { + // videos may be started and stopped. Only add this once + if (navServiceListener == null) { + + navServiceListener = new ISdlServiceListener() { + @Override + public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { + } + + @Override + public void onServiceEnded(SdlSession session, SessionType type) { + // reset nav flags so nav can start upon the next transport connection + resetNavStartFlags(); + // propagate notification up to proxy listener so the developer will know that the service is ended + if (lifecycleListener != null) { + lifecycleListener.onServiceEnded(type); + } + } + + @Override + public void onServiceError(SdlSession session, SessionType type, String reason) { + // if there is an error reset the flags so that there is a chance to restart streaming + resetNavStartFlags(); + } + }; + session.addServiceListener(SessionType.NAV, navServiceListener); + } + } + + /** + * This method will try to start the video service with the requested parameters. + * When it returns it will attempt to store the accepted parameters if available. + * + * @param isEncrypted if the service should be encrypted + * @param parameters the desiered video streaming parameters + */ + private void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return; + } + + session.setDesiredVideoParams(parameters); + + tryStartVideoStream(isEncrypted, parameters); + } + + + /** + * Closes the opened video service (serviceType 11) + * + * @return true if the video service is closed successfully, return false otherwise + */ + private boolean endVideoStream() { + if (session == null) { + return false; + } + + navServiceEndResponseReceived = false; + navServiceEndResponse = false; + session.stopVideoStream(); + + FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceEndResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + + return navServiceEndResponse; + } + + private void startService(SessionType serviceType, boolean isEncrypted) { + session.startService(serviceType, session.getSessionId(), isEncrypted); + } + + + /** + * Closes the opened audio service (serviceType 10) + * + * @return true if the audio service is closed successfully, return false otherwise + */ + private boolean endAudioStream() { + if (session == null || !session.getIsConnected()) return false; + + pcmServiceEndResponseReceived = false; + pcmServiceEndResponse = false; + session.stopAudioStream(); + + FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceEndResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + + return pcmServiceEndResponse; + } + + private class CallableMethod implements Callable { + private final long waitTime; + + public CallableMethod(int timeInMillis) { + this.waitTime = timeInMillis; + } + + @Override + public Void call() { + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + } + + private FutureTask createFutureTask(CallableMethod callMethod) { + return new FutureTask<>(callMethod); + } + + private ScheduledExecutorService createScheduler() { + return Executors.newSingleThreadScheduledExecutor(); + } + + private void NavServiceStarted() { + navServiceStartResponseReceived = true; + navServiceStartResponse = true; + } + + private void NavServiceStartedNACK(List rejectedParams) { + navServiceStartResponseReceived = true; + navServiceStartResponse = false; + navServiceStartRejectedParams = rejectedParams; + } + + private void AudioServiceStarted() { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = true; + } + + private void AudioServiceStartedNACK(List rejectedParams) { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = false; + pcmServiceStartRejectedParams = rejectedParams; + } + + private void NavServiceEnded() { + navServiceEndResponseReceived = true; + navServiceEndResponse = true; + } + + private void NavServiceEndedNACK() { + navServiceEndResponseReceived = true; + navServiceEndResponse = false; + } + + private void AudioServiceEnded() { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = true; + } + + private void AudioServiceEndedNACK() { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = false; + } + + private void resetNavStartFlags() { + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + navServiceStartRejectedParams = null; + } } -- cgit v1.2.1 From f2ee959c1d252d7ecc8537fcb108e8c57f162a8e Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Wed, 3 Jun 2020 10:42:36 -0400 Subject: Cleanup LCM --- .../smartdevicelink/managers/lifecycle/LifecycleManager.java | 10 +++++----- .../managers/lifecycle/BaseLifecycleManager.java | 4 +--- .../smartdevicelink/managers/lifecycle/LifecycleManager.java | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) 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 dca8d0253..66fc880f4 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 @@ -48,15 +48,15 @@ import com.smartdevicelink.transport.enums.TransportType; */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { - public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - super(appConfig, config, listener); + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + super(appConfig, listener); if (config != null && config.getTransportType().equals(TransportType.MULTIPLEX)) { this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) config); - }else if(config != null &&config.getTransportType().equals(TransportType.TCP)){ + } else if (config != null && config.getTransportType().equals(TransportType.TCP)) { this.session = new SdlSession2(sdlConnectionListener, (TCPTransportConfig) config); - }else { - this.session = SdlSession.createSession((byte)getProtocolVersion().getMajor(),sdlConnectionListener, config); + } else { + this.session = SdlSession.createSession((byte) getProtocolVersion().getMajor(), sdlConnectionListener, config); } } } 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 0e62032b5..abafc5313 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -150,11 +150,9 @@ abstract class BaseLifecycleManager { private boolean navServiceEndResponse = false; private boolean pcmServiceEndResponseReceived = false; private boolean pcmServiceEndResponse = false; - private boolean rpcProtectedResponseReceived = false; - private boolean rpcProtectedStartResponse = false; - BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + BaseLifecycleManager(AppConfig appConfig, LifecycleListener listener){ this.lifecycleListener = listener; this.rpcListeners = new HashMap<>(); diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index e3c45516a..0cd661268 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -43,8 +43,8 @@ import com.smartdevicelink.transport.BaseTransportConfig; */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { - public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - super(appConfig, config, listener); + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + super(appConfig, listener); this.session = new SdlSession(sdlConnectionListener, config); } } -- cgit v1.2.1 From afb592c0804c55be7a5ba395f181dc4d50d745f5 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Wed, 3 Jun 2020 13:32:26 -0400 Subject: Move NAV & PCM code to Android LifecycleManager --- .../managers/lifecycle/LifecycleManager.java | 265 +++++++++++++++ .../managers/lifecycle/BaseLifecycleManager.java | 363 +++------------------ 2 files changed, 317 insertions(+), 311 deletions(-) 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 66fc880f4..d4eeff1df 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 @@ -36,18 +36,40 @@ import android.support.annotation.RestrictTo; import com.smartdevicelink.SdlConnection.SdlSession; import com.smartdevicelink.SdlConnection.SdlSession2; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.TCPTransportConfig; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.DebugTool; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledExecutorService; /** * 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. + * * @author Bilal Alsharifi. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { + private static final int RESPONSE_WAIT_TIME = 2000; + private ISdlServiceListener navServiceListener; + private boolean navServiceStartResponseReceived = false; + private boolean navServiceStartResponse = false; + private boolean navServiceEndResponseReceived = false; + private boolean navServiceEndResponse = false; + private boolean pcmServiceStartResponseReceived = false; + private boolean pcmServiceStartResponse = false; + private boolean pcmServiceEndResponseReceived = false; + private boolean pcmServiceEndResponse = false; + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { super(appConfig, listener); @@ -59,4 +81,247 @@ public class LifecycleManager extends BaseLifecycleManager { this.session = SdlSession.createSession((byte) getProtocolVersion().getMajor(), sdlConnectionListener, config); } } + + @Override + void onProtocolSessionStarted(SessionType sessionType) { + super.onProtocolSessionStarted(sessionType); + if (sessionType.eq(SessionType.NAV)) { + navServiceStartResponseReceived = true; + navServiceStartResponse = true; + } else if (sessionType.eq(SessionType.PCM)) { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = true; + } + } + + @Override + void onProtocolSessionStartedNACKed(SessionType sessionType) { + super.onProtocolSessionStartedNACKed(sessionType); + if (sessionType.eq(SessionType.NAV)) { + navServiceStartResponseReceived = true; + navServiceStartResponse = false; + } else if (sessionType.eq(SessionType.PCM)) { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = false; + } + } + + @Override + void onProtocolSessionEnded(SessionType sessionType) { + super.onProtocolSessionEnded(sessionType); + if (sessionType.eq(SessionType.NAV)) { + navServiceEndResponseReceived = true; + navServiceEndResponse = true; + } else if (sessionType.eq(SessionType.PCM)) { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = true; + } + } + + @Override + void onProtocolSessionEndedNACKed(SessionType sessionType) { + super.onProtocolSessionEndedNACKed(sessionType); + if (sessionType.eq(SessionType.NAV)) { + navServiceEndResponseReceived = true; + navServiceEndResponse = false; + } else if (sessionType.eq(SessionType.PCM)) { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = false; + } + } + + /** + * This method will try to start the video service with the requested parameters. + * When it returns it will attempt to store the accepted parameters if available. + * + * @param isEncrypted if the service should be encrypted + * @param parameters the desired video streaming parameters + */ + @Override + void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return; + } + + session.setDesiredVideoParams(parameters); + tryStartVideoStream(isEncrypted, parameters); + } + + /** + * Try to open a video service by using the video streaming parameters supplied. + * Only information from codecs, width and height are used during video format negotiation. + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. + * @return If the service is opened successfully, an instance of VideoStreamingParams is + * returned which contains accepted video format. If the service is opened with legacy + * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is + * returned. If the service was not opened then null is returned. + */ + private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return null; + } + if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) { + DebugTool.logWarning("Module doesn't support video streaming."); + return null; + } + if (parameters == null) { + DebugTool.logWarning("Video parameters were not supplied."); + return null; + } + + if (!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before + || (navServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one + session.setDesiredVideoParams(parameters); + + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + + session.startService(SessionType.NAV, session.getSessionId(), isEncrypted); + addNavListener(); + FutureTask fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceStartResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + } + + if (navServiceStartResponse) { + if (getProtocolVersion() != null && getProtocolVersion().getMajor() < 5) { //Versions 1-4 do not support streaming parameter negotiations + session.setAcceptedVideoParams(parameters); + } + return session.getAcceptedVideoParams(); + } + + return null; + } + + private void addNavListener() { + // videos may be started and stopped. Only add this once + if (navServiceListener == null) { + + navServiceListener = new ISdlServiceListener() { + @Override + public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { + } + + @Override + public void onServiceEnded(SdlSession session, SessionType type) { + // reset nav flags so nav can start upon the next transport connection + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + } + + @Override + public void onServiceError(SdlSession session, SessionType type, String reason) { + // if there is an error reset the flags so that there is a chance to restart streaming + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + } + }; + session.addServiceListener(SessionType.NAV, navServiceListener); + } + } + + /** + * Closes the opened video service (serviceType 11) + * + * @return true if the video service is closed successfully, return false otherwise + */ + @Override + boolean endVideoStream() { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return false; + } + if (!session.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return false; + } + + navServiceEndResponseReceived = false; + navServiceEndResponse = false; + session.stopVideoStream(); + + FutureTask fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceEndResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + + return navServiceEndResponse; + } + + @Override + void startAudioService(boolean isEncrypted) { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return; + } + session.startService(SessionType.PCM, session.getSessionId(), isEncrypted); + } + + /** + * Closes the opened audio service (serviceType 10) + * + * @return true if the audio service is closed successfully, return false otherwise + */ + @Override + boolean endAudioStream() { + if (session == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return false; + } + if (!session.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return false; + } + + pcmServiceEndResponseReceived = false; + pcmServiceEndResponse = false; + session.stopAudioStream(); + + FutureTask fTask = new FutureTask<>(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceEndResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + + return pcmServiceEndResponse; + } + + private class CallableMethod implements Callable { + private final long waitTime; + + public CallableMethod(int timeInMillis) { + this.waitTime = timeInMillis; + } + + @Override + public Void call() { + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + } } 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 abafc5313..b56336dbb 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,7 @@ package com.smartdevicelink.managers.lifecycle; +import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.RestrictTo; import android.util.Log; @@ -138,20 +139,6 @@ abstract class BaseLifecycleManager { Version minimumProtocolVersion; Version minimumRPCVersion; - private static final int RESPONSE_WAIT_TIME = 2000; - private ISdlServiceListener navServiceListener; - private boolean navServiceStartResponseReceived = false; - private boolean navServiceStartResponse = false; - private List navServiceStartRejectedParams = null; - private boolean pcmServiceStartResponseReceived = false; - private boolean pcmServiceStartResponse = false; - private List pcmServiceStartRejectedParams = null; - private boolean navServiceEndResponseReceived = false; - private boolean navServiceEndResponse = false; - private boolean pcmServiceEndResponseReceived = false; - private boolean pcmServiceEndResponse = false; - - BaseLifecycleManager(AppConfig appConfig, LifecycleListener listener){ this.lifecycleListener = listener; @@ -916,86 +903,23 @@ abstract class BaseLifecycleManager { @Override public void onProtocolSessionStartedNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID, List rejectedParams) { Log.w(TAG, sessionType + " onProtocolSessionStartedNACKed " + sessionID + " RejectedParams: " + rejectedParams); - - if (sessionType.eq(SessionType.NAV)) { - NavServiceStartedNACK(rejectedParams); - } - else if (sessionType.eq(SessionType.PCM)) { - AudioServiceStartedNACK(rejectedParams); - } + BaseLifecycleManager.this.onProtocolSessionStartedNACKed(sessionType); } @Override public void onProtocolSessionStarted(SessionType sessionType, byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted) { - Log.i(TAG, "on protocol session started"); - if (sessionType != null) { - if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { - Log.w(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, session.getSessionId()); - cleanProxy(); - return; - } - - if (sessionType.equals(SessionType.RPC)) { - if (appConfig != null) { - - appConfig.prepare(); - - SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(); - sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor()); - sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor()); - sdlMsgVersion.setPatchVersion(MAX_SUPPORTED_RPC_VERSION.getPatch()); - - RegisterAppInterface rai = new RegisterAppInterface(sdlMsgVersion, - appConfig.getAppName(), appConfig.isMediaApp(), appConfig.getLanguageDesired(), - appConfig.getHmiDisplayLanguageDesired(), appConfig.getAppID()); - rai.setCorrelationID(REGISTER_APP_INTERFACE_CORRELATION_ID); - - rai.setTtsName(appConfig.getTtsName()); - rai.setNgnMediaScreenAppName(appConfig.getNgnMediaScreenAppName()); - rai.setVrSynonyms(appConfig.getVrSynonyms()); - rai.setAppHMIType(appConfig.getAppType()); - rai.setDayColorScheme(appConfig.getDayColorScheme()); - rai.setNightColorScheme(appConfig.getNightColorScheme()); - - //Add device/system info in the future - //TODO attach previous hash id - - sendRPCMessagePrivate(rai); - } else { - Log.e(TAG, "App config was null, soo..."); - } - - - } else if (sessionType.eq(SessionType.NAV)) { - NavServiceStarted(); - } else if (sessionType.eq(SessionType.PCM)) { - AudioServiceStarted(); - } else { - lifecycleListener.onServiceStarted(sessionType); - } - } + BaseLifecycleManager.this.onProtocolSessionStarted(sessionType); } @Override public void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID) { - if (sessionType.eq(SessionType.NAV)) { - NavServiceEnded(); - } - else if (sessionType.eq(SessionType.PCM)) { - AudioServiceEnded(); - } + BaseLifecycleManager.this.onProtocolSessionEnded(sessionType); } @Override public void onProtocolSessionEndedNACKed(SessionType sessionType, byte sessionID, String correlationID) { - if (sessionType.eq(SessionType.NAV)) { - NavServiceEndedNACK(); - } - else if (sessionType.eq(SessionType.PCM)) { - AudioServiceEndedNACK(); - } + BaseLifecycleManager.this.onProtocolSessionEndedNACKed(sessionType); } @Override @@ -1053,16 +977,12 @@ abstract class BaseLifecycleManager { @Override public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { - if(isConnected()){ - BaseLifecycleManager.this.startVideoService(encrypted,parameters); - } + BaseLifecycleManager.this.startVideoService(encrypted, parameters); } @Override public void stopVideoService() { - if(isConnected()){ - BaseLifecycleManager.this.endVideoStream(); - } + BaseLifecycleManager.this.endVideoStream(); } @Override @@ -1078,16 +998,12 @@ abstract class BaseLifecycleManager { @Override public void startAudioService(boolean encrypted) { - if(isConnected()){ - BaseLifecycleManager.this.startService(SessionType.PCM, encrypted); - } + BaseLifecycleManager.this.startAudioService(encrypted); } @Override public void stopAudioService() { - if(isConnected()){ - BaseLifecycleManager.this.endAudioStream(); - } + BaseLifecycleManager.this.endAudioStream(); } @Override @@ -1514,242 +1430,67 @@ abstract class BaseLifecycleManager { } } + /* ******************************************************************************************************* + ********************************** Platform specific methods - START ************************************* + *********************************************************************************************************/ - - - ///////////////////////////// - - /** - * Try to open a video service by using the video streaming parameters supplied. - *

- * Only information from codecs, width and height are used during video format negotiation. - * - * @param isEncrypted Specify true if packets on this service have to be encrypted - * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. - * @return If the service is opened successfully, an instance of VideoStreamingParams is - * returned which contains accepted video format. If the service is opened with legacy - * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is - * returned. If the service was not opened then null is returned. - */ - private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { - if (session == null) { - DebugTool.logWarning("SdlSession is not created yet."); - return null; - } - if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) { - DebugTool.logWarning("Module doesn't support video streaming."); - return null; - } - if (parameters == null) { - DebugTool.logWarning("Video parameters were not supplied."); - return null; - } - - if (!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before - || (navServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one - session.setDesiredVideoParams(parameters); - - navServiceStartResponseReceived = false; - navServiceStartResponse = false; - navServiceStartRejectedParams = null; - - session.startService(SessionType.NAV, session.getSessionId(), isEncrypted); - addNavListener(); - FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); - ScheduledExecutorService scheduler = createScheduler(); - scheduler.execute(fTask); - - //noinspection StatementWithEmptyBody - while (!navServiceStartResponseReceived && !fTask.isDone()) ; - scheduler.shutdown(); - } - - if (navServiceStartResponse) { - if (getProtocolVersion() != null && getProtocolVersion().getMajor() < 5) { //Versions 1-4 do not support streaming parameter negotiations - session.setAcceptedVideoParams(parameters); + void onProtocolSessionStarted (SessionType sessionType) { + if (sessionType != null) { + if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { + Log.w(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, session.getSessionId()); + cleanProxy(); + return; } - return session.getAcceptedVideoParams(); - } - return null; - } + if (sessionType.equals(SessionType.RPC)) { + if (appConfig != null) { - private void addNavListener() { - // videos may be started and stopped. Only add this once - if (navServiceListener == null) { + appConfig.prepare(); - navServiceListener = new ISdlServiceListener() { - @Override - public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { - } + SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(); + sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor()); + sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor()); + sdlMsgVersion.setPatchVersion(MAX_SUPPORTED_RPC_VERSION.getPatch()); - @Override - public void onServiceEnded(SdlSession session, SessionType type) { - // reset nav flags so nav can start upon the next transport connection - resetNavStartFlags(); - // propagate notification up to proxy listener so the developer will know that the service is ended - if (lifecycleListener != null) { - lifecycleListener.onServiceEnded(type); - } - } + RegisterAppInterface rai = new RegisterAppInterface(sdlMsgVersion, + appConfig.getAppName(), appConfig.isMediaApp(), appConfig.getLanguageDesired(), + appConfig.getHmiDisplayLanguageDesired(), appConfig.getAppID()); + rai.setCorrelationID(REGISTER_APP_INTERFACE_CORRELATION_ID); - @Override - public void onServiceError(SdlSession session, SessionType type, String reason) { - // if there is an error reset the flags so that there is a chance to restart streaming - resetNavStartFlags(); - } - }; - session.addServiceListener(SessionType.NAV, navServiceListener); - } - } - - /** - * This method will try to start the video service with the requested parameters. - * When it returns it will attempt to store the accepted parameters if available. - * - * @param isEncrypted if the service should be encrypted - * @param parameters the desiered video streaming parameters - */ - private void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) { - if (session == null) { - DebugTool.logWarning("SdlSession is not created yet."); - return; - } - if (!session.getIsConnected()) { - DebugTool.logWarning("Connection is not available."); - return; - } - - session.setDesiredVideoParams(parameters); - - tryStartVideoStream(isEncrypted, parameters); - } - - - /** - * Closes the opened video service (serviceType 11) - * - * @return true if the video service is closed successfully, return false otherwise - */ - private boolean endVideoStream() { - if (session == null) { - return false; - } - - navServiceEndResponseReceived = false; - navServiceEndResponse = false; - session.stopVideoStream(); - - FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); - ScheduledExecutorService scheduler = createScheduler(); - scheduler.execute(fTask); - - //noinspection StatementWithEmptyBody - while (!navServiceEndResponseReceived && !fTask.isDone()) ; - scheduler.shutdown(); - - return navServiceEndResponse; - } - - private void startService(SessionType serviceType, boolean isEncrypted) { - session.startService(serviceType, session.getSessionId(), isEncrypted); - } - - - /** - * Closes the opened audio service (serviceType 10) - * - * @return true if the audio service is closed successfully, return false otherwise - */ - private boolean endAudioStream() { - if (session == null || !session.getIsConnected()) return false; + rai.setTtsName(appConfig.getTtsName()); + rai.setNgnMediaScreenAppName(appConfig.getNgnMediaScreenAppName()); + rai.setVrSynonyms(appConfig.getVrSynonyms()); + rai.setAppHMIType(appConfig.getAppType()); + rai.setDayColorScheme(appConfig.getDayColorScheme()); + rai.setNightColorScheme(appConfig.getNightColorScheme()); - pcmServiceEndResponseReceived = false; - pcmServiceEndResponse = false; - session.stopAudioStream(); + //Add device/system info in the future + //TODO attach previous hash id - FutureTask fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); - ScheduledExecutorService scheduler = createScheduler(); - scheduler.execute(fTask); - - //noinspection StatementWithEmptyBody - while (!pcmServiceEndResponseReceived && !fTask.isDone()) ; - scheduler.shutdown(); - - return pcmServiceEndResponse; - } - - private class CallableMethod implements Callable { - private final long waitTime; - - public CallableMethod(int timeInMillis) { - this.waitTime = timeInMillis; - } - - @Override - public Void call() { - try { - Thread.sleep(waitTime); - } catch (InterruptedException e) { - e.printStackTrace(); + sendRPCMessagePrivate(rai); + } else { + Log.e(TAG, "App config was null, soo..."); + } } - return null; } } - private FutureTask createFutureTask(CallableMethod callMethod) { - return new FutureTask<>(callMethod); - } + void onProtocolSessionStartedNACKed (SessionType sessionType) {} - private ScheduledExecutorService createScheduler() { - return Executors.newSingleThreadScheduledExecutor(); - } + void onProtocolSessionEnded (SessionType sessionType) {} - private void NavServiceStarted() { - navServiceStartResponseReceived = true; - navServiceStartResponse = true; - } - - private void NavServiceStartedNACK(List rejectedParams) { - navServiceStartResponseReceived = true; - navServiceStartResponse = false; - navServiceStartRejectedParams = rejectedParams; - } - - private void AudioServiceStarted() { - pcmServiceStartResponseReceived = true; - pcmServiceStartResponse = true; - } - - private void AudioServiceStartedNACK(List rejectedParams) { - pcmServiceStartResponseReceived = true; - pcmServiceStartResponse = false; - pcmServiceStartRejectedParams = rejectedParams; - } + void onProtocolSessionEndedNACKed (SessionType sessionType) {} - private void NavServiceEnded() { - navServiceEndResponseReceived = true; - navServiceEndResponse = true; - } + void startVideoService(boolean encrypted, VideoStreamingParameters parameters) {} - private void NavServiceEndedNACK() { - navServiceEndResponseReceived = true; - navServiceEndResponse = false; - } + boolean endVideoStream() { return false; } - private void AudioServiceEnded() { - pcmServiceEndResponseReceived = true; - pcmServiceEndResponse = true; - } + void startAudioService(boolean encrypted) {} - private void AudioServiceEndedNACK() { - pcmServiceEndResponseReceived = true; - pcmServiceEndResponse = false; - } + boolean endAudioStream() { return false; } - private void resetNavStartFlags() { - navServiceStartResponseReceived = false; - navServiceStartResponse = false; - navServiceStartRejectedParams = null; - } + /* ******************************************************************************************************* + ********************************** Platform specific methods - End ************************************* + *********************************************************************************************************/ } -- cgit v1.2.1 From dddd3f79355f707d223a2accf37d7d753369946b Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Wed, 3 Jun 2020 13:39:17 -0400 Subject: Remove unused imports --- .../com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java | 5 ----- 1 file changed, 5 deletions(-) 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 b56336dbb..cb60b4452 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -32,7 +32,6 @@ package com.smartdevicelink.managers.lifecycle; -import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.RestrictTo; import android.util.Log; @@ -100,11 +99,7 @@ import com.smartdevicelink.util.Version; import java.util.HashMap; import java.util.List; import java.util.Vector; -import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import java.util.concurrent.ScheduledExecutorService; abstract class BaseLifecycleManager { -- cgit v1.2.1 From 3c28c2367b0eba1cc5b5ee9c572ba67518c5140b Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Wed, 3 Jun 2020 16:07:28 -0400 Subject: Fix potential NPE in hello sdl java --- hello_sdl_java/src/main/java/com/smartdevicelink/java/Main.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hello_sdl_java/src/main/java/com/smartdevicelink/java/Main.java b/hello_sdl_java/src/main/java/com/smartdevicelink/java/Main.java index 446c267ee..f34ab0df2 100644 --- a/hello_sdl_java/src/main/java/com/smartdevicelink/java/Main.java +++ b/hello_sdl_java/src/main/java/com/smartdevicelink/java/Main.java @@ -68,8 +68,10 @@ public class Main { static SdlService.SdlServiceCallback serviceCallback = new SdlService.SdlServiceCallback() { @Override public void onEnd() { - thread.interrupt(); - thread = null; + if (thread != null) { + thread.interrupt(); + thread = null; + } synchronized (LOCK) { LOCK.notify(); } -- cgit v1.2.1 From 54706b28b458a3ce38247ee6f64a9641460b1595 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Wed, 3 Jun 2020 17:05:55 -0400 Subject: Update formatting --- .../managers/lifecycle/BaseLifecycleManager.java | 20 ++++++++++---------- .../java/com/smartdevicelink/util/NativeLogTool.java | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) 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 cb60b4452..9eb544419 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -962,12 +962,12 @@ abstract class BaseLifecycleManager { @Override public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - BaseLifecycleManager.this.session.addServiceListener(serviceType,sdlServiceListener); + BaseLifecycleManager.this.session.addServiceListener(serviceType, sdlServiceListener); } @Override public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - BaseLifecycleManager.this.session.removeServiceListener(serviceType,sdlServiceListener); + BaseLifecycleManager.this.session.removeServiceListener(serviceType, sdlServiceListener); } @Override @@ -1014,34 +1014,34 @@ abstract class BaseLifecycleManager { @Override public void sendRPC(RPCMessage message) { - if(isConnected()) { + if (isConnected()) { BaseLifecycleManager.this.sendRPCMessagePrivate(message); } } @Override public void sendRequests(List rpcs, OnMultipleRequestListener listener) { - BaseLifecycleManager.this.sendRPCs(rpcs,listener); + BaseLifecycleManager.this.sendRPCs(rpcs, listener); } @Override public void sendRPCs(List rpcs, OnMultipleRequestListener listener) { - BaseLifecycleManager.this.sendRPCs(rpcs,listener); + BaseLifecycleManager.this.sendRPCs(rpcs, listener); } @Override public void sendSequentialRPCs(List rpcs, OnMultipleRequestListener listener) { - BaseLifecycleManager.this.sendSequentialRPCs(rpcs,listener); + BaseLifecycleManager.this.sendSequentialRPCs(rpcs, listener); } @Override public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - BaseLifecycleManager.this.addOnRPCNotificationListener(notificationId,listener); + BaseLifecycleManager.this.addOnRPCNotificationListener(notificationId, listener); } @Override public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - return BaseLifecycleManager.this.removeOnRPCNotificationListener(notificationId,listener); + return BaseLifecycleManager.this.removeOnRPCNotificationListener(notificationId, listener); } @Override @@ -1056,12 +1056,12 @@ abstract class BaseLifecycleManager { @Override public void addOnRPCListener(FunctionID responseId, OnRPCListener listener) { - BaseLifecycleManager.this.addRpcListener(responseId,listener); + BaseLifecycleManager.this.addRpcListener(responseId, listener); } @Override public boolean removeOnRPCListener(FunctionID responseId, OnRPCListener listener) { - return BaseLifecycleManager.this.removeOnRPCListener(responseId,listener); + return BaseLifecycleManager.this.removeOnRPCListener(responseId, listener); } @Override diff --git a/base/src/main/java/com/smartdevicelink/util/NativeLogTool.java b/base/src/main/java/com/smartdevicelink/util/NativeLogTool.java index f125fb5ac..ced98a083 100644 --- a/base/src/main/java/com/smartdevicelink/util/NativeLogTool.java +++ b/base/src/main/java/com/smartdevicelink/util/NativeLogTool.java @@ -130,7 +130,7 @@ public class NativeLogTool { break; } if (bytesWritten < chunk.length()) { - Log.e(TAG, "Calling Log.e: msg length=" + chunk.length() + ", bytesWritten=" + bytesWritten); + Log.w(TAG, "Calling Log.e: msg length=" + chunk.length() + ", bytesWritten=" + bytesWritten); } } } catch (Exception ex) { -- cgit v1.2.1 From 8a6e18e90d2c4702e354f63bd6fb2d0184181d1f Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 4 Jun 2020 11:47:44 -0400 Subject: Remove old checkLifecycleConfiguration method --- .../smartdevicelink/managers/BaseSdlManager.java | 54 ---------------------- 1 file changed, 54 deletions(-) diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 6f716a7dd..e4e7b0f32 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -238,60 +238,6 @@ abstract class BaseSdlManager { } } - protected void checkLifecycleConfiguration2() { - final Language actualLanguage = lifecycleManager.getRegisterAppInterfaceResponse().getLanguage(); - - if (actualLanguage != null && !actualLanguage.equals(hmiLanguage)) { - - final LifecycleConfigurationUpdate lcu = managerListener.managerShouldUpdateLifecycle(actualLanguage); - - if (lcu != null) { - ChangeRegistration changeRegistration = new ChangeRegistration(actualLanguage, actualLanguage); - changeRegistration.setAppName(lcu.getAppName()); - changeRegistration.setNgnMediaScreenAppName(lcu.getShortAppName()); - changeRegistration.setTtsName(lcu.getTtsName()); - changeRegistration.setVrSynonyms(lcu.getVoiceRecognitionCommandNames()); - changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()) { - // go through and change sdlManager properties that were changed via the LCU update - hmiLanguage = actualLanguage; - - if (lcu.getAppName() != null) { - appName = lcu.getAppName(); - } - - if (lcu.getShortAppName() != null) { - shortAppName = lcu.getShortAppName(); - } - - if (lcu.getTtsName() != null) { - ttsChunks = lcu.getTtsName(); - } - - if (lcu.getVoiceRecognitionCommandNames() != null) { - vrSynonyms = lcu.getVoiceRecognitionCommandNames(); - } - } - try { - Log.v(TAG, response.serializeJSON().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - DebugTool.logError("Change Registration onError: " + resultCode + " | Info: " + info); - retryChangeRegistration(); - } - }); - _internalInterface.sendRPC(changeRegistration); - } - } - } - /** * Get the current state for the SdlManager * @return int value that represents the current state -- cgit v1.2.1 From 64023263a5a8a22bd32f7d2511e0422309a3c5d0 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 4 Jun 2020 16:25:07 -0400 Subject: Prevent sending RPC with protected CorrelationID --- .../smartdevicelink/managers/BaseSdlManager.java | 1 - .../managers/lifecycle/BaseLifecycleManager.java | 47 ++++++++++++++++------ .../managers/lifecycle/PoliciesFetcher.java | 2 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index e4e7b0f32..2ffaeab73 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -172,7 +172,6 @@ abstract class BaseSdlManager { abstract void initialize(); public abstract void dispose(); - protected void checkLifecycleConfiguration(){ final Language actualLanguage = this.getRegisterAppInterfaceResponse().getLanguage(); final Language actualHMILanguage = this.getRegisterAppInterfaceResponse().getHmiDisplayLanguage(); 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 9eb544419..1e5b0dd57 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -211,10 +211,10 @@ abstract class BaseLifecycleManager { } }); } - sendRPCMessagePrivate(request); + sendRPCMessagePrivate(request, false); }else { // Notifications and Responses - sendRPCMessagePrivate(message); + sendRPCMessagePrivate(message, false); if (listener != null){ listener.onUpdate(messages.size()); if (messages.size() == 0){ @@ -273,10 +273,10 @@ abstract class BaseLifecycleManager { sendSequentialRPCs(messages, listener); } }); - sendRPCMessagePrivate(request); + sendRPCMessagePrivate(request, false); } else { // Notifications and Responses - sendRPCMessagePrivate(rpc); + sendRPCMessagePrivate(rpc, false); if (listener != null) { listener.onUpdate(messages.size()); } @@ -387,7 +387,7 @@ abstract class BaseLifecycleManager { Log.w(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); + sendRPCMessagePrivate(msg, true); cleanProxy(); return; } @@ -414,7 +414,7 @@ abstract class BaseLifecycleManager { public void run() { RPCRequest request = PoliciesFetcher.fetchPolicies(onSystemRequest); if (request != null && isConnected()) { - sendRPCMessagePrivate(request); + sendRPCMessagePrivate(request, true); } } }; @@ -432,7 +432,7 @@ abstract class BaseLifecycleManager { systemRequest.setBulkData(file); systemRequest.setRequestType(RequestType.ICON_URL); if (isConnected()) { - sendRPCMessagePrivate(systemRequest); + sendRPCMessagePrivate(systemRequest, true); } } else { DebugTool.logError("File was null at: " + urlHttps); @@ -721,8 +721,29 @@ abstract class BaseLifecycleManager { **************************************** RPC LISTENERS !! END !! **************************************** *********************************************************************************************************/ - private void sendRPCMessagePrivate(RPCMessage message){ + private void sendRPCMessagePrivate(RPCMessage message, boolean isInternalMessage){ try { + if (!isInternalMessage && message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) message; + OnRPCResponseListener listener = request.getOnRPCResponseListener(); + + // Test for illegal correlation ID + if (request.getCorrelationID() == REGISTER_APP_INTERFACE_CORRELATION_ID || request.getCorrelationID() == UNREGISTER_APP_INTERFACE_CORRELATION_ID || request.getCorrelationID() == PoliciesFetcher.POLICIES_CORRELATION_ID) { + if (listener != null) { + request.getOnRPCResponseListener().onError(request.getCorrelationID(), Result.REJECTED, "Invalid correlation ID. The correlation ID, " + request.getCorrelationID() + " , is a reserved correlation ID."); + } + return; + } + + // Prevent developer from sending RAI or UAI manually + if (request.getFunctionName().equals(FunctionID.REGISTER_APP_INTERFACE.toString()) || request.getFunctionName().equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) { + if (listener != null) { + request.getOnRPCResponseListener().onError(request.getCorrelationID(), Result.REJECTED, "The RPCRequest, " + message.getFunctionName() + ", is un-allowed to be sent manually by the developer."); + } + return; + } + } + //FIXME this is temporary until the next major release of the library where OK is removed if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { RPCRequest request = (RPCRequest) message; @@ -744,7 +765,7 @@ abstract class BaseLifecycleManager { RPCRequest request2 = new RPCRequest(request); request2.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.PLAY_PAUSE); request2.setOnRPCResponseListener(request.getOnRPCResponseListener()); - sendRPCMessagePrivate(request2); + sendRPCMessagePrivate(request2, true); return; } } @@ -933,8 +954,8 @@ abstract class BaseLifecycleManager { public void onAuthTokenReceived(String token, byte sessionID) { BaseLifecycleManager.this.authToken = token; } - }; + /* ******************************************************************************************************* *************************************** ISdlConnectionListener END ************************************ *********************************************************************************************************/ @@ -1009,13 +1030,13 @@ abstract class BaseLifecycleManager { @Override public void sendRPCRequest(RPCRequest message) { - BaseLifecycleManager.this.sendRPCMessagePrivate(message); + BaseLifecycleManager.this.sendRPCMessagePrivate(message, false); } @Override public void sendRPC(RPCMessage message) { if (isConnected()) { - BaseLifecycleManager.this.sendRPCMessagePrivate(message); + BaseLifecycleManager.this.sendRPCMessagePrivate(message, false); } } @@ -1463,7 +1484,7 @@ abstract class BaseLifecycleManager { //Add device/system info in the future //TODO attach previous hash id - sendRPCMessagePrivate(rai); + sendRPCMessagePrivate(rai, true); } else { Log.e(TAG, "App config was null, soo..."); } diff --git a/base/src/main/java/com/smartdevicelink/managers/lifecycle/PoliciesFetcher.java b/base/src/main/java/com/smartdevicelink/managers/lifecycle/PoliciesFetcher.java index f8d59261a..714686a96 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/PoliciesFetcher.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/PoliciesFetcher.java @@ -55,7 +55,7 @@ import java.util.Vector; class PoliciesFetcher { private static final String TAG = PoliciesFetcher.class.getSimpleName(); - private static final int POLICIES_CORRELATION_ID = 65535; + static final int POLICIES_CORRELATION_ID = 65535; private static HttpURLConnection getURLConnection(Headers myHeader, String sURLString, int Timeout, int iContentLen) { String sContentType = "application/json"; -- cgit v1.2.1 From 454c3e3a6682d5bcf136d6b1087482591c3ab11b Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 4 Jun 2020 16:31:31 -0400 Subject: Update getProtocolVersion() to return default version if value is null --- .../smartdevicelink/managers/lifecycle/BaseLifecycleManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 1e5b0dd57..5f8bdc90d 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -171,11 +171,11 @@ abstract class BaseLifecycleManager { session.close(); } - Version getProtocolVersion(){ - if (session != null){ + Version getProtocolVersion() { + if (session != null && session.getProtocolVersion() != null) { return session.getProtocolVersion(); } - return new Version(1,0,0); + return new Version(1, 0, 0); } private void sendRPCs(List messages, final OnMultipleRequestListener listener){ -- cgit v1.2.1 From ed4286b4dd410a03cf32d7ecb842ec102c8fac49 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 5 Jun 2020 11:23:19 -0400 Subject: Update formatting in SdlManager --- javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index 82381a7ce..06240d4e0 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -70,8 +70,7 @@ public class SdlManager extends BaseSdlManager { Log.i(TAG, "start"); if (lifecycleManager == null) { - if (transport != null - && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { + if (transport != null && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { super.start(); } else { throw new RuntimeException("No transport provided"); -- cgit v1.2.1 From 3622381b0d5a99a941302bdde1ef3c4b0f353f8c Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 5 Jun 2020 11:53:48 -0400 Subject: Add logic to set SdlSecurityBase.context --- .../com/smartdevicelink/managers/SdlManager.java | 3 +++ .../managers/lifecycle/LifecycleManager.java | 21 +++++++++++++++++++++ .../smartdevicelink/managers/BaseSdlManager.java | 2 -- .../managers/lifecycle/BaseLifecycleManager.java | 4 ++++ .../com/smartdevicelink/managers/SdlManager.java | 1 + 5 files changed, 29 insertions(+), 2 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 86697f0b4..e1d92c61d 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 @@ -116,6 +116,9 @@ public class SdlManager extends BaseSdlManager{ } super.start(); + + lifecycleManager.setContext(context); + lifecycleManager.start(); } } 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 d4eeff1df..c3b7fa560 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 android.app.Service; +import android.content.Context; import android.support.annotation.RestrictTo; import com.smartdevicelink.SdlConnection.SdlSession; @@ -39,6 +41,7 @@ import com.smartdevicelink.SdlConnection.SdlSession2; import com.smartdevicelink.protocol.enums.SessionType; import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.security.SdlSecurityBase; import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; @@ -69,6 +72,7 @@ public class LifecycleManager extends BaseLifecycleManager { private boolean pcmServiceStartResponse = false; private boolean pcmServiceEndResponseReceived = false; private boolean pcmServiceEndResponse = false; + private Context context; public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { super(appConfig, listener); @@ -82,6 +86,23 @@ public class LifecycleManager extends BaseLifecycleManager { } } + @RestrictTo(RestrictTo.Scope.LIBRARY) + public void setContext(Context context) { + this.context = context; + } + + @Override + void setSdlSecurityStaticVars() { + super.setSdlSecurityStaticVars(); + + Service service = null; + if (context != null && context instanceof Service) { + service = (Service) context; + } + SdlSecurityBase.setAppService(service); + SdlSecurityBase.setContext(context); + } + @Override void onProtocolSessionStarted(SessionType sessionType) { super.onProtocolSessionStarted(sessionType); diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 2ffaeab73..42eaea168 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -341,8 +341,6 @@ abstract class BaseSdlManager { //Setup the notification queue initNotificationQueue(); - - lifecycleManager.start(); } void onReady(){ 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 5f8bdc90d..f2fc4aebf 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -1424,6 +1424,8 @@ abstract class BaseLifecycleManager { if (_secList == null) return; + setSdlSecurityStaticVars(); + SdlSecurityBase sec; for (Class cls : _secList) { @@ -1506,6 +1508,8 @@ abstract class BaseLifecycleManager { boolean endAudioStream() { return false; } + void setSdlSecurityStaticVars() {}; + /* ******************************************************************************************************* ********************************** Platform specific methods - End ************************************* *********************************************************************************************************/ diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index 06240d4e0..cdb42dd7b 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -72,6 +72,7 @@ public class SdlManager extends BaseSdlManager { if (lifecycleManager == null) { if (transport != null && (transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER) || transport.getTransportType().equals(TransportType.CUSTOM))) { super.start(); + lifecycleManager.start(); } else { throw new RuntimeException("No transport provided"); } -- cgit v1.2.1 From f45dc766fa5c8e7bcd236e5db0bf8af966f5d5b0 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 5 Jun 2020 13:59:29 -0400 Subject: Remove deprecated methods usage in SdlManager --- .../main/java/com/smartdevicelink/managers/BaseSdlManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 42eaea168..0f96d7b1c 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -352,13 +352,13 @@ abstract class BaseSdlManager { public void onComplete(boolean success) { if (success) { SetAppIcon msg = new SetAppIcon(BaseSdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); + _internalInterface.sendRPC(msg); } } }); } else { SetAppIcon msg = new SetAppIcon(BaseSdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); + _internalInterface.sendRPC(msg); } } } @@ -488,7 +488,7 @@ abstract class BaseSdlManager { /** * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests asynchronously, use sendRequests
+ * For sending requests asynchronously, use sendRPCs
* * NOTE: This will override any listeners on individual RPCs
* @@ -530,7 +530,7 @@ abstract class BaseSdlManager { } if (rpcRequestList.size() > 0) { - _internalInterface.sendRequests(rpcRequestList,listener); + _internalInterface.sendRPCs(rpcRequestList,listener); } } -- cgit v1.2.1 From 582014293e69ec06d96f7b0d9d3fd59f748deb35 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 5 Jun 2020 13:59:44 -0400 Subject: Fix SdlManager unit tests --- .../smartdevicelink/managers/SdlManagerTests.java | 50 ++++++++++------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java index 589af4c52..6ea265f52 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java @@ -1,16 +1,16 @@ package com.smartdevicelink.managers; import android.content.Context; +import android.os.Looper; import com.smartdevicelink.AndroidTestCase2; -import com.smartdevicelink.exception.SdlException; import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; import com.smartdevicelink.managers.lockscreen.LockScreenConfig; import com.smartdevicelink.protocol.enums.FunctionID; import com.smartdevicelink.proxy.RPCMessage; import com.smartdevicelink.proxy.RPCRequest; import com.smartdevicelink.proxy.RPCResponse; -import com.smartdevicelink.proxy.SdlProxyBase; +import com.smartdevicelink.proxy.interfaces.ISdl; import com.smartdevicelink.proxy.rpc.GetAppServiceDataResponse; import com.smartdevicelink.proxy.rpc.GetVehicleData; import com.smartdevicelink.proxy.rpc.OnAppServiceData; @@ -49,7 +49,7 @@ public class SdlManagerTests extends AndroidTestCase2 { private TemplateColorScheme templateColorScheme; private int listenerCalledCounter; private SdlManager sdlManager; - private SdlProxyBase sdlProxyBase; + private ISdl internalInterface; // transport related @SuppressWarnings("FieldCanBeLocal") @@ -136,9 +136,9 @@ public class SdlManagerTests extends AndroidTestCase2 { builder.setContext(mTestContext); manager = builder.build(); - // mock SdlProxyBase and set it manually - sdlProxyBase = mock(SdlProxyBase.class); - manager.setProxy(sdlProxyBase); + // mock internalInterface and set it manually + internalInterface = mock(ISdl.class); + manager._internalInterface = internalInterface; return manager; } @@ -184,8 +184,11 @@ public class SdlManagerTests extends AndroidTestCase2 { public void testStartingManager(){ listenerCalledCounter = 0; - - sdlManager.start(); + + try { + sdlManager.start(); + } catch (Exception e) { + } // Create and force all sub managers to be ready manually. Because SdlManager will not start until all sub managers are ready. // Note: SdlManager.initialize() will not be called automatically by proxy as in real life because we have mock proxy not a real one @@ -198,7 +201,7 @@ public class SdlManagerTests extends AndroidTestCase2 { sdlManager.getLockScreenManager().transitionToState(BaseSubManager.READY); // Make sure the listener is called exactly once - assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1); + assertEquals("Listener was not called or called more/less frequently than expected", 1, listenerCalledCounter); } public void testManagerStates() { @@ -314,7 +317,7 @@ public class SdlManagerTests extends AndroidTestCase2 { public void testSendRPC(){ listenerCalledCounter = 0; - // When sdlProxyBase.sendRPCRequest() is called, create a fake success response + // When internalInterface.sendRPC() is called, create a fake success response Answer answer = new Answer() { @Override public Void answer(InvocationOnMock invocation) { @@ -326,11 +329,7 @@ public class SdlManagerTests extends AndroidTestCase2 { return null; } }; - try { - doAnswer(answer).when(sdlProxyBase).sendRPC(any(RPCMessage.class)); - } catch (SdlException e) { - e.printStackTrace(); - } + doAnswer(answer).when(internalInterface).sendRPC(any(RPCMessage.class)); // Test send RPC request @@ -347,7 +346,7 @@ public class SdlManagerTests extends AndroidTestCase2 { sdlManager.sendRPC(request); // Make sure the listener is called exactly once - assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1); + assertEquals("Listener was not called or called more/less frequently than expected", 1, listenerCalledCounter); } public void testSendRPCs(){ @@ -361,7 +360,7 @@ public class SdlManagerTests extends AndroidTestCase2 { private void testSendMultipleRPCs(boolean sequentialSend){ listenerCalledCounter = 0; - // When sdlProxyBase.sendRPCRequests() is called, call listener.onFinished() to fake the response + // When internalInterface.sendRPCs() is called, call listener.onFinished() to fake the response final Answer answer = new Answer() { @Override public Void answer(InvocationOnMock invocation) { @@ -371,18 +370,16 @@ public class SdlManagerTests extends AndroidTestCase2 { return null; } }; - try { - if (sequentialSend){ - doAnswer(answer).when(sdlProxyBase).sendSequentialRequests(any(List.class), any(OnMultipleRequestListener.class)); - } else { - doAnswer(answer).when(sdlProxyBase).sendRequests(any(List.class), any(OnMultipleRequestListener.class)); - } - } catch (SdlException e) { - e.printStackTrace(); + if (sequentialSend){ + doAnswer(answer).when(internalInterface).sendSequentialRPCs(any(List.class), any(OnMultipleRequestListener.class)); + + } else { + doAnswer(answer).when(internalInterface).sendRPCs(any(List.class), any(OnMultipleRequestListener.class)); } + // Test send RPC requests List rpcsList = Arrays.asList(new GetVehicleData(), new Show(), new OnAppServiceData(), new GetAppServiceDataResponse()); OnMultipleRequestListener onMultipleRequestListener = new OnMultipleRequestListener() { @@ -408,7 +405,6 @@ public class SdlManagerTests extends AndroidTestCase2 { // Make sure the listener is called exactly once - assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1); + assertEquals("Listener was not called or called more/less frequently than expected", 1, listenerCalledCounter); } - } -- cgit v1.2.1 From a65389af0a19e9ec54beb1080a1b7e64c8660914 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Fri, 5 Jun 2020 17:11:11 -0400 Subject: Remove unused import --- .../androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java index 6ea265f52..77097a9c1 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java @@ -1,7 +1,6 @@ package com.smartdevicelink.managers; import android.content.Context; -import android.os.Looper; import com.smartdevicelink.AndroidTestCase2; import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; -- cgit v1.2.1 From 9a9cc73fa4a540218ac4b9442a498401243da1db Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Mon, 8 Jun 2020 09:59:19 -0400 Subject: Remove unsed vars from LifecycleManager --- .../com/smartdevicelink/managers/lifecycle/LifecycleManager.java | 8 -------- 1 file changed, 8 deletions(-) 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 c3b7fa560..be95cf928 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 @@ -68,8 +68,6 @@ public class LifecycleManager extends BaseLifecycleManager { private boolean navServiceStartResponse = false; private boolean navServiceEndResponseReceived = false; private boolean navServiceEndResponse = false; - private boolean pcmServiceStartResponseReceived = false; - private boolean pcmServiceStartResponse = false; private boolean pcmServiceEndResponseReceived = false; private boolean pcmServiceEndResponse = false; private Context context; @@ -109,9 +107,6 @@ public class LifecycleManager extends BaseLifecycleManager { if (sessionType.eq(SessionType.NAV)) { navServiceStartResponseReceived = true; navServiceStartResponse = true; - } else if (sessionType.eq(SessionType.PCM)) { - pcmServiceStartResponseReceived = true; - pcmServiceStartResponse = true; } } @@ -121,9 +116,6 @@ public class LifecycleManager extends BaseLifecycleManager { if (sessionType.eq(SessionType.NAV)) { navServiceStartResponseReceived = true; navServiceStartResponse = false; - } else if (sessionType.eq(SessionType.PCM)) { - pcmServiceStartResponseReceived = true; - pcmServiceStartResponse = false; } } -- cgit v1.2.1 From 97ecbfab51b1e61788565dc328eaa039b6f6f857 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Mon, 8 Jun 2020 14:44:01 -0400 Subject: add createSession method to LCM --- .../com/smartdevicelink/managers/lifecycle/LifecycleManager.java | 5 ++++- .../smartdevicelink/managers/lifecycle/BaseLifecycleManager.java | 8 ++++++-- .../com/smartdevicelink/managers/lifecycle/LifecycleManager.java | 5 ++++- 3 files changed, 14 insertions(+), 4 deletions(-) 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 be95cf928..eb6ab2fd9 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 @@ -73,8 +73,11 @@ public class LifecycleManager extends BaseLifecycleManager { private Context context; public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { - super(appConfig, listener); + super(appConfig, config, listener); + } + @Override + void createSession(BaseTransportConfig config) { if (config != null && config.getTransportType().equals(TransportType.MULTIPLEX)) { this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) config); } else if (config != null && config.getTransportType().equals(TransportType.TCP)) { 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 f2fc4aebf..4be04d403 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -134,7 +134,7 @@ abstract class BaseLifecycleManager { Version minimumProtocolVersion; Version minimumRPCVersion; - BaseLifecycleManager(AppConfig appConfig, LifecycleListener listener){ + BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ this.lifecycleListener = listener; this.rpcListeners = new HashMap<>(); @@ -147,6 +147,8 @@ abstract class BaseLifecycleManager { this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); + + createSession(config); } public void start(){ @@ -1452,6 +1454,8 @@ abstract class BaseLifecycleManager { ********************************** Platform specific methods - START ************************************* *********************************************************************************************************/ + abstract void createSession(BaseTransportConfig config); + void onProtocolSessionStarted (SessionType sessionType) { if (sessionType != null) { if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { @@ -1508,7 +1512,7 @@ abstract class BaseLifecycleManager { boolean endAudioStream() { return false; } - void setSdlSecurityStaticVars() {}; + void setSdlSecurityStaticVars() {} /* ******************************************************************************************************* ********************************** Platform specific methods - End ************************************* diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index 0cd661268..47ed40727 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -44,7 +44,10 @@ import com.smartdevicelink.transport.BaseTransportConfig; @RestrictTo(RestrictTo.Scope.LIBRARY) public class LifecycleManager extends BaseLifecycleManager { public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { - super(appConfig, listener); + super(appConfig, config, listener); + } + + void createSession(BaseTransportConfig config) { this.session = new SdlSession(sdlConnectionListener, config); } } -- cgit v1.2.1 From e6498f057b86c21310fd5e9d1ba2c593e31ef5a5 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Tue, 9 Jun 2020 11:33:41 -0400 Subject: Add cycle proxy logic to LCM --- .../managers/lifecycle/LifecycleManager.java | 63 +++++++++++++++++++--- .../smartdevicelink/managers/BaseSdlManager.java | 10 ++-- .../managers/lifecycle/BaseLifecycleManager.java | 39 +++++++------- .../managers/lifecycle/LifecycleManager.java | 14 ++++- 4 files changed, 92 insertions(+), 34 deletions(-) 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 eb6ab2fd9..d29029aaf 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 @@ -35,20 +35,27 @@ package com.smartdevicelink.managers.lifecycle; import android.app.Service; import android.content.Context; import android.support.annotation.RestrictTo; +import android.util.Log; import com.smartdevicelink.SdlConnection.SdlSession; import com.smartdevicelink.SdlConnection.SdlSession2; +import com.smartdevicelink.exception.SdlException; +import com.smartdevicelink.exception.SdlExceptionCause; import com.smartdevicelink.protocol.enums.SessionType; import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; import com.smartdevicelink.security.SdlSecurityBase; import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.TCPTransportConfig; +import com.smartdevicelink.transport.USBTransportConfig; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.util.DebugTool; +import java.util.ArrayList; +import java.util.Collections; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; @@ -77,13 +84,45 @@ public class LifecycleManager extends BaseLifecycleManager { } @Override - void createSession(BaseTransportConfig config) { - if (config != null && config.getTransportType().equals(TransportType.MULTIPLEX)) { - this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) config); - } else if (config != null && config.getTransportType().equals(TransportType.TCP)) { - this.session = new SdlSession2(sdlConnectionListener, (TCPTransportConfig) config); + void initializeProxy() { + super.initializeProxy(); + + //Handle legacy USB connections + if (_transportConfig != null && TransportType.USB.equals(_transportConfig.getTransportType())) { + //A USB transport config was provided + USBTransportConfig usbTransportConfig = (USBTransportConfig) _transportConfig; + if (usbTransportConfig.getUsbAccessory() == null) { + DebugTool.logInfo("Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service"); + //The accessory was null which means it came from a router service + MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(), appConfig.getAppID()); + multiplexTransportConfig.setRequiresHighBandwidth(true); + multiplexTransportConfig.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF); + multiplexTransportConfig.setPrimaryTransports(Collections.singletonList(TransportType.USB)); + multiplexTransportConfig.setSecondaryTransports(new ArrayList()); + _transportConfig = multiplexTransportConfig; + } + } + + if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.MULTIPLEX)) { + this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) _transportConfig); + } else if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.TCP)) { + this.session = new SdlSession2(sdlConnectionListener, (TCPTransportConfig) _transportConfig); } else { - this.session = SdlSession.createSession((byte) getProtocolVersion().getMajor(), sdlConnectionListener, config); + this.session = SdlSession.createSession((byte) getProtocolVersion().getMajor(), sdlConnectionListener, _transportConfig); + } + } + + private void cycleProxy(SdlDisconnectedReason disconnectedReason) { + cleanProxy(); + initializeProxy(); + 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)); + } + try { + session.startSession(); + } catch (SdlException e) { + e.printStackTrace(); } } @@ -113,6 +152,18 @@ public class LifecycleManager extends BaseLifecycleManager { } } + @Override + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig){ + super.onTransportDisconnected(info, availablePrimary, transportConfig); + if (availablePrimary) { + _transportConfig = transportConfig; + Log.d(TAG, "notifying RPC session ended, but potential primary transport available"); + cycleProxy(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST); + } else { + onClose(info, null); + } + } + @Override void onProtocolSessionStartedNACKed(SessionType sessionType) { super.onProtocolSessionStartedNACKed(sessionType); diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 0f96d7b1c..14e1eae49 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -120,17 +120,13 @@ abstract class BaseSdlManager { // Initialize with anonymous lifecycleListener final LifecycleManager.LifecycleListener lifecycleListener = new LifecycleManager.LifecycleListener() { - boolean initStarted = false; @Override public void onProxyConnected(LifecycleManager lifeCycleManager) { Log.i(TAG,"Proxy is connected. Now initializing."); synchronized (this){ - if(!initStarted){ - changeRegistrationRetry = 0; - checkLifecycleConfiguration(); - initialize(); - initStarted = true; - } + changeRegistrationRetry = 0; + checkLifecycleConfiguration(); + initialize(); } } @Override 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 4be04d403..4a12c18c1 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -103,7 +103,7 @@ import java.util.concurrent.CopyOnWriteArrayList; abstract class BaseLifecycleManager { - private static final String TAG = "Lifecycle Manager"; + static final String TAG = "Lifecycle Manager"; public static final Version MAX_SUPPORTED_RPC_VERSION = new Version(6, 0, 0); // Protected Correlation IDs @@ -133,27 +133,19 @@ abstract class BaseLifecycleManager { private String authToken; Version minimumProtocolVersion; Version minimumRPCVersion; + BaseTransportConfig _transportConfig; BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ - this.lifecycleListener = listener; - - this.rpcListeners = new HashMap<>(); - this.rpcResponseListeners = new HashMap<>(); - this.rpcNotificationListeners = new HashMap<>(); - this.rpcRequestListeners = new HashMap<>(); - this.appConfig = appConfig; + this._transportConfig = config; + this.lifecycleListener = listener; this.minimumProtocolVersion = appConfig.getMinimumProtocolVersion(); this.minimumRPCVersion = appConfig.getMinimumRPCVersion(); - - this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); - - createSession(config); + initializeProxy(); } public void start(){ try { - setupInternalRpcListeners(); session.startSession(); } catch (SdlException e) { e.printStackTrace(); @@ -333,7 +325,7 @@ abstract class BaseLifecycleManager { return currentHMIStatus; } - private void onClose(String info, Exception e){ + void onClose(String info, Exception e){ Log.i(TAG, "onClose"); if(lifecycleListener != null){ lifecycleListener.onProxyClosed((LifecycleManager) this, info,e,null); @@ -864,9 +856,7 @@ abstract class BaseLifecycleManager { @Override public void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { - if (!availablePrimary) { - onClose(info, null); - } + BaseLifecycleManager.this.onTransportDisconnected(info, availablePrimary, transportConfig); } @@ -1377,7 +1367,9 @@ abstract class BaseLifecycleManager { return null; } - private void cleanProxy(){ + void cleanProxy(){ + firstTimeFull = true; + currentHMIStatus = null; if (rpcListeners != null) { rpcListeners.clear(); } @@ -1454,7 +1446,14 @@ abstract class BaseLifecycleManager { ********************************** Platform specific methods - START ************************************* *********************************************************************************************************/ - abstract void createSession(BaseTransportConfig config); + void initializeProxy(){ + this.rpcListeners = new HashMap<>(); + this.rpcResponseListeners = new HashMap<>(); + this.rpcNotificationListeners = new HashMap<>(); + this.rpcRequestListeners = new HashMap<>(); + this.systemCapabilityManager = new SystemCapabilityManager(internalInterface); + setupInternalRpcListeners(); + } void onProtocolSessionStarted (SessionType sessionType) { if (sessionType != null) { @@ -1498,6 +1497,8 @@ abstract class BaseLifecycleManager { } } + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) {} + void onProtocolSessionStartedNACKed (SessionType sessionType) {} void onProtocolSessionEnded (SessionType sessionType) {} diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java index 47ed40727..4a5e3747d 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -47,7 +47,17 @@ public class LifecycleManager extends BaseLifecycleManager { super(appConfig, config, listener); } - void createSession(BaseTransportConfig config) { - this.session = new SdlSession(sdlConnectionListener, config); + @Override + void initializeProxy() { + super.initializeProxy(); + this.session = new SdlSession(sdlConnectionListener, _transportConfig); + } + + @Override + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { + super.onTransportDisconnected(info, availablePrimary, transportConfig); + if (!availablePrimary) { + onClose(info, null); + } } } -- cgit v1.2.1 From 4c025a72c44c53a7b9ff6fbf88aad62d0a840771 Mon Sep 17 00:00:00 2001 From: Bilal Alsharifi Date: Thu, 11 Jun 2020 14:35:15 -0400 Subject: Update formatting --- .../smartdevicelink/managers/SdlManagerTests.java | 14 +- .../com/smartdevicelink/managers/SdlManager.java | 607 +++++++++++---------- .../managers/lifecycle/LifecycleManager.java | 4 +- .../smartdevicelink/managers/BaseSdlManager.java | 205 ++++--- .../managers/lifecycle/BaseLifecycleManager.java | 313 ++++++----- .../com/smartdevicelink/managers/SdlManager.java | 33 +- 6 files changed, 641 insertions(+), 535 deletions(-) diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java index 77097a9c1..84865f21e 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java @@ -356,7 +356,7 @@ public class SdlManagerTests extends AndroidTestCase2 { testSendMultipleRPCs(true); } - private void testSendMultipleRPCs(boolean sequentialSend){ + private void testSendMultipleRPCs(boolean sequentialSend) { listenerCalledCounter = 0; // When internalInterface.sendRPCs() is called, call listener.onFinished() to fake the response @@ -370,7 +370,7 @@ public class SdlManagerTests extends AndroidTestCase2 { } }; - if (sequentialSend){ + if (sequentialSend) { doAnswer(answer).when(internalInterface).sendSequentialRPCs(any(List.class), any(OnMultipleRequestListener.class)); } else { @@ -378,12 +378,12 @@ public class SdlManagerTests extends AndroidTestCase2 { } - // Test send RPC requests List rpcsList = Arrays.asList(new GetVehicleData(), new Show(), new OnAppServiceData(), new GetAppServiceDataResponse()); OnMultipleRequestListener onMultipleRequestListener = new OnMultipleRequestListener() { @Override - public void onUpdate(int remainingRequests) { } + public void onUpdate(int remainingRequests) { + } @Override public void onFinished() { @@ -391,10 +391,12 @@ public class SdlManagerTests extends AndroidTestCase2 { } @Override - public void onError(int correlationId, Result resultCode, String info) {} + public void onError(int correlationId, Result resultCode, String info) { + } @Override - public void onResponse(int correlationId, RPCResponse response) {} + public void onResponse(int correlationId, RPCResponse response) { + } }; if (sequentialSend) { sdlManager.sendSequentialRPCs(rpcsList, onMultipleRequestListener); 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 e1d92c61d..2a34dc62e 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 @@ -60,318 +60,333 @@ import java.util.List; /** * SDLManager
- * + *

* This is the main point of contact between an application and SDL
- * + *

* It is broken down to these areas:
- * + *

* 1. SDLManagerBuilder
* 2. ISdl Interface along with its overridden methods - This can be passed into attached managers
* 3. Sending Requests
* 4. Helper methods */ -public class SdlManager extends BaseSdlManager{ - private Context context; - private LockScreenConfig lockScreenConfig; - - // Managers - private LockScreenManager lockScreenManager; - private VideoStreamManager videoStreamManager; - private AudioStreamManager audioStreamManager; - - /** - * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up - */ - @Override - public void start(){ - if (lifecycleManager == null) { - if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ - //Do the thing - MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); - final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); - multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { - @Override - public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { - - //Pass to submanagers that need it - if(videoStreamManager != null){ - videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - - if(audioStreamManager != null){ - audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - //If the developer supplied a listener to start, it is time to call that - if(devListener != null){ - devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); - } - } - }); - - //If the requires audio support has not been set, it should be set to true if the - //app is a media app, and false otherwise - if(multiplexTransportConfig.requiresAudioSupport() == null){ - multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); - } - } - - super.start(); - - lifecycleManager.setContext(context); - lifecycleManager.start(); - } - } - - @Override - protected void initialize(){ - // Instantiate sub managers - this.permissionManager = new PermissionManager(_internalInterface); - this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); - if (lockScreenConfig.isEnabled()) { - this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); - } - this.screenManager = new ScreenManager(_internalInterface, this.fileManager); - if(getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)){ - this.videoStreamManager = new VideoStreamManager(_internalInterface); - } else { - this.videoStreamManager = null; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) ) { - this.audioStreamManager = new AudioStreamManager(_internalInterface, context); - } else { - this.audioStreamManager = null; - } - - // Start sub managers - this.permissionManager.start(subManagerListener); - this.fileManager.start(subManagerListener); - if (lockScreenConfig.isEnabled()){ - this.lockScreenManager.start(subManagerListener); - } - this.screenManager.start(subManagerListener); - } - - @Override - void checkState() { - if (permissionManager != null && fileManager != null && screenManager != null && (!lockScreenConfig.isEnabled() || lockScreenManager != null)) { - if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY && (!lockScreenConfig.isEnabled() || lockScreenManager.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 && (!lockScreenConfig.isEnabled() || lockScreenManager.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 || (lockScreenConfig.isEnabled() && lockScreenManager != null && lockScreenManager.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! - } else { - Log.w(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); - transitionToState(BaseSubManager.LIMITED); - handleQueuedNotifications(); - notifyDevListener(null); - onReady(); - } - } else { - // We should never be here, but somehow one of the sub-sub managers is null - String info = "ERROR one of the sdl sub managers is null"; - Log.e(TAG, info); - transitionToState(BaseSubManager.ERROR); - notifyDevListener(info); - } - } - - private void notifyDevListener(String info) { - if (managerListener != null) { - if (getState() == BaseSubManager.ERROR){ - managerListener.onError(info, null); - } else { - managerListener.onStart(); - } - } - } - - @Override - void retryChangeRegistration() { - changeRegistrationRetry++; - if (changeRegistrationRetry < MAX_RETRY) { - final Handler handler = new Handler(Looper.getMainLooper()); - handler.postDelayed(new Runnable() { - @Override - public void run() { - checkLifecycleConfiguration(); - DebugTool.logInfo("Retry Change Registration Count: " + changeRegistrationRetry); - } - }, 3000); - } - } - - @Override - void onProxyClosed(SdlDisconnectedReason reason) { - Log.i(TAG,"Proxy is closed."); - if(managerListener != null){ - managerListener.onDestroy(); - } - - if (reason == null || !reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ - dispose(); - } - } - - /** Dispose SdlManager and clean its resources - * Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed. - */ - @SuppressLint("NewApi") - @Override - public void dispose() { - if (this.permissionManager != null) { - this.permissionManager.dispose(); - } - - if (this.fileManager != null) { - this.fileManager.dispose(); - } - - if (this.lockScreenManager != null) { - this.lockScreenManager.dispose(); - } - - if (this.screenManager != null) { - this.screenManager.dispose(); - } - - if(this.videoStreamManager != null) { - this.videoStreamManager.dispose(); - } - - // SuppressLint("NewApi") is used because audioStreamManager is only available on android >= jelly bean - if (this.audioStreamManager != null) { - this.audioStreamManager.dispose(); - } - - if (this.lifecycleManager != null) { - this.lifecycleManager.stop(); - } - - if(managerListener != null){ - managerListener.onDestroy(); - managerListener = null; - } - - transitionToState(BaseSubManager.SHUTDOWN); - } - - // MANAGER GETTERS +public class SdlManager extends BaseSdlManager { + private Context context; + private LockScreenConfig lockScreenConfig; + + // Managers + private LockScreenManager lockScreenManager; + private VideoStreamManager videoStreamManager; + private AudioStreamManager audioStreamManager; + + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @Override + public void start() { + if (lifecycleManager == null) { + if (transport != null && transport.getTransportType() == TransportType.MULTIPLEX) { + //Do the thing + MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig) (transport); + final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); + multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { + @Override + public void onTransportEvent(List connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { + + //Pass to submanagers that need it + if (videoStreamManager != null) { + videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + + if (audioStreamManager != null) { + audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + //If the developer supplied a listener to start, it is time to call that + if (devListener != null) { + devListener.onTransportEvent(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + } + }); + + //If the requires audio support has not been set, it should be set to true if the + //app is a media app, and false otherwise + if (multiplexTransportConfig.requiresAudioSupport() == null) { + multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); + } + } + + super.start(); + + lifecycleManager.setContext(context); + lifecycleManager.start(); + } + } + + @Override + protected void initialize() { + // Instantiate sub managers + this.permissionManager = new PermissionManager(_internalInterface); + this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); + if (lockScreenConfig.isEnabled()) { + this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); + } + this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + if (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) { + this.videoStreamManager = new VideoStreamManager(_internalInterface); + } else { + this.videoStreamManager = null; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION))) { + this.audioStreamManager = new AudioStreamManager(_internalInterface, context); + } else { + this.audioStreamManager = null; + } + + // Start sub managers + this.permissionManager.start(subManagerListener); + this.fileManager.start(subManagerListener); + if (lockScreenConfig.isEnabled()) { + this.lockScreenManager.start(subManagerListener); + } + this.screenManager.start(subManagerListener); + } + + @Override + void checkState() { + if (permissionManager != null && fileManager != null && screenManager != null && (!lockScreenConfig.isEnabled() || lockScreenManager != null)) { + if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY && (!lockScreenConfig.isEnabled() || lockScreenManager.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 && (!lockScreenConfig.isEnabled() || lockScreenManager.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 || (lockScreenConfig.isEnabled() && lockScreenManager != null && lockScreenManager.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! + } else { + Log.w(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); + transitionToState(BaseSubManager.LIMITED); + handleQueuedNotifications(); + notifyDevListener(null); + onReady(); + } + } else { + // We should never be here, but somehow one of the sub-sub managers is null + String info = "ERROR one of the sdl sub managers is null"; + Log.e(TAG, info); + transitionToState(BaseSubManager.ERROR); + notifyDevListener(info); + } + } + + private void notifyDevListener(String info) { + if (managerListener != null) { + if (getState() == BaseSubManager.ERROR) { + managerListener.onError(info, null); + } else { + managerListener.onStart(); + } + } + } + + @Override + void retryChangeRegistration() { + changeRegistrationRetry++; + if (changeRegistrationRetry < MAX_RETRY) { + final Handler handler = new Handler(Looper.getMainLooper()); + handler.postDelayed(new Runnable() { + @Override + public void run() { + checkLifecycleConfiguration(); + DebugTool.logInfo("Retry Change Registration Count: " + changeRegistrationRetry); + } + }, 3000); + } + } + + @Override + void onProxyClosed(SdlDisconnectedReason reason) { + Log.i(TAG, "Proxy is closed."); + if (managerListener != null) { + managerListener.onDestroy(); + } + + if (reason == null || !reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)) { + dispose(); + } + } + + /** + * Dispose SdlManager and clean its resources + * Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed. + */ + @SuppressLint("NewApi") + @Override + public void dispose() { + if (this.permissionManager != null) { + this.permissionManager.dispose(); + } + + if (this.fileManager != null) { + this.fileManager.dispose(); + } + + if (this.lockScreenManager != null) { + this.lockScreenManager.dispose(); + } + + if (this.screenManager != null) { + this.screenManager.dispose(); + } + + if (this.videoStreamManager != null) { + this.videoStreamManager.dispose(); + } + + // SuppressLint("NewApi") is used because audioStreamManager is only available on android >= jelly bean + if (this.audioStreamManager != null) { + this.audioStreamManager.dispose(); + } + + if (this.lifecycleManager != null) { + this.lifecycleManager.stop(); + } + + if (managerListener != null) { + managerListener.onDestroy(); + managerListener = null; + } + + transitionToState(BaseSubManager.SHUTDOWN); + } + + // MANAGER GETTERS + /** * Gets the VideoStreamManager.
- * The VideoStreamManager returned will only be not null if the registered app type is - * either NAVIGATION or PROJECTION. Once the VideoStreamManager is retrieved, its start() - * method will need to be called before use. + * The VideoStreamManager returned will only be not null if the registered app type is + * either NAVIGATION or PROJECTION. Once the VideoStreamManager is retrieved, its start() + * method will need to be called before use. *

Note: VideoStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a VideoStreamManager object attached to this SdlManager instance */ - public @Nullable VideoStreamManager getVideoStreamManager() { - checkSdlManagerState(); - return videoStreamManager; - } + public @Nullable + VideoStreamManager getVideoStreamManager() { + checkSdlManagerState(); + return videoStreamManager; + } /** * Gets the AudioStreamManager.
- * The AudioStreamManager returned will only be not null if the registered app type is - * either NAVIGATION or PROJECTION. Once the AudioStreamManager is retrieved, its start() - * method will need to be called before use. + * The AudioStreamManager returned will only be not null if the registered app type is + * either NAVIGATION or PROJECTION. Once the AudioStreamManager is retrieved, its start() + * method will need to be called before use. *
Note: AudioStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a AudioStreamManager object */ - public @Nullable AudioStreamManager getAudioStreamManager() { - checkSdlManagerState(); - return audioStreamManager; - } - - /** - * Gets the LockScreenManager.
- * Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. - * @return a LockScreenManager object - */ - public LockScreenManager getLockScreenManager() { - if (lockScreenManager.getState() != BaseSubManager.READY && lockScreenManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "LockScreenManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return lockScreenManager; - } - - // PROTECTED GETTERS - protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; } - - // BUILDER - public static class Builder extends BaseSdlManager.Builder{ - /** - * Builder for the SdlManager. Parameters in the constructor are required. - * @param context the current context - * @param appId the app's ID - * @param appName the app's name - * @param listener a SdlManagerListener object - */ - public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ - super(appId, appName, listener); - setContext(context); - } - /** - * Builder for the SdlManager. Parameters in the constructor are required. - * @param context the current context - * @param appId the app's ID - * @param appName the app's name - * @param listener a SdlManagerListener object - */ - public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull BaseTransportConfig transport, @NonNull final SdlManagerListener listener){ - super(appId, appName, listener); - setContext(context); - setTransportType(transport); - } - - /** - * Sets the LockScreenConfig for the session.
- * Note: If not set, the default configuration will be used. - * @param lockScreenConfig - configuration options - */ - public Builder setLockScreenConfig (final LockScreenConfig lockScreenConfig){ - sdlManager.lockScreenConfig = lockScreenConfig; - return this; - } - - /** - * Sets the Context - * @param context the current context - */ - public Builder setContext(Context context){ - sdlManager.context = context; - return this; - } - - /** - * Build SdlManager ang get it ready to be started - * Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed. - * @return SdlManager instance that is ready to be started - */ - public SdlManager build() { - if (sdlManager.transport == null) { - throw new IllegalArgumentException("You must set a transport type object"); - } - - if (sdlManager.lockScreenConfig == null){ - // if lock screen params are not set, use default - sdlManager.lockScreenConfig = new LockScreenConfig(); - } - - super.build(); - - return sdlManager; - } - } + public @Nullable + AudioStreamManager getAudioStreamManager() { + checkSdlManagerState(); + return audioStreamManager; + } + + /** + * Gets the LockScreenManager.
+ * Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * + * @return a LockScreenManager object + */ + public LockScreenManager getLockScreenManager() { + if (lockScreenManager.getState() != BaseSubManager.READY && lockScreenManager.getState() != BaseSubManager.LIMITED) { + Log.e(TAG, "LockScreenManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return lockScreenManager; + } + + // PROTECTED GETTERS + protected LockScreenConfig getLockScreenConfig() { + return lockScreenConfig; + } + + // BUILDER + public static class Builder extends BaseSdlManager.Builder { + /** + * Builder for the SdlManager. Parameters in the constructor are required. + * + * @param context the current context + * @param appId the app's ID + * @param appName the app's name + * @param listener a SdlManagerListener object + */ + public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener) { + super(appId, appName, listener); + setContext(context); + } + + /** + * Builder for the SdlManager. Parameters in the constructor are required. + * + * @param context the current context + * @param appId the app's ID + * @param appName the app's name + * @param listener a SdlManagerListener object + */ + public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull BaseTransportConfig transport, @NonNull final SdlManagerListener listener) { + super(appId, appName, listener); + setContext(context); + setTransportType(transport); + } + + /** + * Sets the LockScreenConfig for the session.
+ * Note: If not set, the default configuration will be used. + * + * @param lockScreenConfig - configuration options + */ + public Builder setLockScreenConfig(final LockScreenConfig lockScreenConfig) { + sdlManager.lockScreenConfig = lockScreenConfig; + return this; + } + + /** + * Sets the Context + * + * @param context the current context + */ + public Builder setContext(Context context) { + sdlManager.context = context; + return this; + } + + /** + * Build SdlManager ang get it ready to be started + * Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed. + * + * @return SdlManager instance that is ready to be started + */ + public SdlManager build() { + if (sdlManager.transport == null) { + throw new IllegalArgumentException("You must set a transport type object"); + } + + if (sdlManager.lockScreenConfig == null) { + // if lock screen params are not set, use default + sdlManager.lockScreenConfig = new LockScreenConfig(); + } + + super.build(); + + return sdlManager; + } + } } 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 d29029aaf..777e29f1b 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 @@ -115,7 +115,7 @@ public class LifecycleManager extends BaseLifecycleManager { private void cycleProxy(SdlDisconnectedReason disconnectedReason) { cleanProxy(); initializeProxy(); - if(!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason) && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(disconnectedReason)){ + 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)); } @@ -153,7 +153,7 @@ public class LifecycleManager extends BaseLifecycleManager { } @Override - void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig){ + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { super.onTransportDisconnected(info, availablePrimary, transportConfig); if (availablePrimary) { _transportConfig = transportConfig; diff --git a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java index 14e1eae49..c52f27b2d 100644 --- a/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/BaseSdlManager.java @@ -122,20 +122,21 @@ abstract class BaseSdlManager { final LifecycleManager.LifecycleListener lifecycleListener = new LifecycleManager.LifecycleListener() { @Override public void onProxyConnected(LifecycleManager lifeCycleManager) { - Log.i(TAG,"Proxy is connected. Now initializing."); - synchronized (this){ + Log.i(TAG, "Proxy is connected. Now initializing."); + synchronized (this) { changeRegistrationRetry = 0; checkLifecycleConfiguration(); initialize(); } } + @Override - public void onServiceStarted(SessionType sessionType){ + public void onServiceStarted(SessionType sessionType) { } @Override - public void onServiceEnded(SessionType sessionType){ + public void onServiceEnded(SessionType sessionType) { } @@ -154,7 +155,7 @@ abstract class BaseSdlManager { final CompletionListener subManagerListener = new CompletionListener() { @Override public synchronized void onComplete(boolean success) { - if(!success){ + if (!success) { Log.e(TAG, "Sub manager failed to initialize"); } checkState(); @@ -163,14 +164,18 @@ abstract class BaseSdlManager { // ABSTRACT METHODS abstract void retryChangeRegistration(); + abstract void onProxyClosed(SdlDisconnectedReason reason); + abstract void checkState(); + abstract void initialize(); + public abstract void dispose(); - protected void checkLifecycleConfiguration(){ - final Language actualLanguage = this.getRegisterAppInterfaceResponse().getLanguage(); - final Language actualHMILanguage = this.getRegisterAppInterfaceResponse().getHmiDisplayLanguage(); + protected void checkLifecycleConfiguration() { + final Language actualLanguage = this.getRegisterAppInterfaceResponse().getLanguage(); + final Language actualHMILanguage = this.getRegisterAppInterfaceResponse().getHmiDisplayLanguage(); if ((actualLanguage != null && !actualLanguage.equals(language)) || (actualHMILanguage != null && !actualHMILanguage.equals(hmiLanguage))) { @@ -194,7 +199,7 @@ abstract class BaseSdlManager { changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()){ + if (response.getSuccess()) { // go through and change sdlManager properties that were changed via the LCU update hmiLanguage = actualHMILanguage; language = actualLanguage; @@ -235,6 +240,7 @@ abstract class BaseSdlManager { /** * Get the current state for the SdlManager + * * @return int value that represents the current state * @see BaseSubManager */ @@ -250,13 +256,13 @@ abstract class BaseSdlManager { } } - void checkSdlManagerState(){ - if (getState() != BaseSubManager.READY && getState() != BaseSubManager.LIMITED){ + void checkSdlManagerState() { + if (getState() != BaseSubManager.READY && getState() != BaseSubManager.LIMITED) { Log.e(TAG, "SdlManager is not ready for use, be sure to initialize with start() method, implement callback, and use SubManagers in the SdlManager's callback"); } } - void initNotificationQueue(){ + void initNotificationQueue() { //Setup the notification queue if (onRPCNotificationListeners != null) { Set functionIDSet = onRPCNotificationListeners.keySet(); @@ -275,7 +281,7 @@ abstract class BaseSdlManager { } } - void handleQueuedNotifications(){ + void handleQueuedNotifications() { //Handle queued notifications and add the listeners if (onRPCNotificationListeners != null) { Set functionIDSet = onRPCNotificationListeners.keySet(); @@ -312,7 +318,7 @@ abstract class BaseSdlManager { * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up */ @SuppressWarnings("unchecked") - public void start(){ + public void start() { LifecycleManager.AppConfig appConfig = new LifecycleManager.AppConfig(); appConfig.setAppName(appName); //short app name @@ -339,7 +345,7 @@ abstract class BaseSdlManager { initNotificationQueue(); } - void onReady(){ + void onReady() { // Set the app icon if (BaseSdlManager.this.appIcon != null && BaseSdlManager.this.appIcon.getName() != null) { if (fileManager != null && fileManager.getState() == BaseSubManager.READY && !fileManager.hasUploadedFile(BaseSdlManager.this.appIcon)) { @@ -360,43 +366,73 @@ abstract class BaseSdlManager { } // PROTECTED GETTERS - protected String getAppName() { return appName; } + protected String getAppName() { + return appName; + } - protected String getAppId() { return appId; } + protected String getAppId() { + return appId; + } - protected String getShortAppName() { return shortAppName; } + protected String getShortAppName() { + return shortAppName; + } - protected Version getMinimumProtocolVersion() { return minimumProtocolVersion; } + protected Version getMinimumProtocolVersion() { + return minimumProtocolVersion; + } - protected Version getMinimumRPCVersion() { return minimumRPCVersion; } + protected Version getMinimumRPCVersion() { + return minimumRPCVersion; + } - protected Language getHmiLanguage() { return hmiLanguage; } + protected Language getHmiLanguage() { + return hmiLanguage; + } - protected Language getLanguage() { return language; } + protected Language getLanguage() { + return language; + } - protected TemplateColorScheme getDayColorScheme() { return dayColorScheme; } + protected TemplateColorScheme getDayColorScheme() { + return dayColorScheme; + } - protected TemplateColorScheme getNightColorScheme() { return nightColorScheme; } + protected TemplateColorScheme getNightColorScheme() { + return nightColorScheme; + } - protected Vector getAppTypes() { return hmiTypes; } + protected Vector getAppTypes() { + return hmiTypes; + } - protected Vector getVrSynonyms() { return vrSynonyms; } + protected Vector getVrSynonyms() { + return vrSynonyms; + } - protected Vector getTtsChunks() { return ttsChunks; } + protected Vector getTtsChunks() { + return ttsChunks; + } - protected BaseTransportConfig getTransport() { return transport; } + protected BaseTransportConfig getTransport() { + return transport; + } - protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } + protected FileManagerConfig getFileManagerConfig() { + return fileManagerConfig; + } // MANAGER GETTERS + /** * Gets the PermissionManager.
* Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a PermissionManager object */ public PermissionManager getPermissionManager() { - if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG,"PermissionManager should not be accessed because it is not in READY/LIMITED state"); + if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED) { + Log.e(TAG, "PermissionManager should not be accessed because it is not in READY/LIMITED state"); } checkSdlManagerState(); return permissionManager; @@ -405,10 +441,11 @@ abstract class BaseSdlManager { /** * Gets the FileManager.
* Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a FileManager object */ public FileManager getFileManager() { - if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED){ + if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED) { Log.e(TAG, "FileManager should not be accessed because it is not in READY/LIMITED state"); } checkSdlManagerState(); @@ -418,10 +455,11 @@ abstract class BaseSdlManager { /** * Gets the ScreenManager.
* Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a ScreenManager object */ public ScreenManager getScreenManager() { - if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED){ + if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED) { Log.e(TAG, "ScreenManager should not be accessed because it is not in READY/LIMITED state"); } checkSdlManagerState(); @@ -431,9 +469,10 @@ abstract class BaseSdlManager { /** * Gets the SystemCapabilityManager.
* Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully. + * * @return a SystemCapabilityManager object */ - public SystemCapabilityManager getSystemCapabilityManager(){ + public SystemCapabilityManager getSystemCapabilityManager() { return lifecycleManager.getSystemCapabilityManager((SdlManager) this); } @@ -445,8 +484,8 @@ abstract class BaseSdlManager { * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet * registered with the module. */ - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ - if(lifecycleManager != null){ + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { + if (lifecycleManager != null) { return lifecycleManager.getRegisterAppInterfaceResponse(); } return null; @@ -454,10 +493,11 @@ abstract class BaseSdlManager { /** * Get the current OnHMIStatus + * * @return OnHMIStatus object represents the current OnHMIStatus */ - public OnHMIStatus getCurrentHMIStatus(){ - if(this.lifecycleManager !=null ){ + public OnHMIStatus getCurrentHMIStatus() { + if (this.lifecycleManager != null) { return lifecycleManager.getCurrentHMIStatus(); } return null; @@ -466,9 +506,10 @@ abstract class BaseSdlManager { /** * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC * service from the module. For example, this should be used to login to a user account. + * * @return the string representation of the auth token */ - public String getAuthToken(){ + public String getAuthToken() { return this.lifecycleManager.getAuthToken(); } @@ -476,6 +517,7 @@ abstract class BaseSdlManager { /** * Send RPC Message
+ * * @param message RPCMessage */ public void sendRPC(RPCMessage message) { @@ -490,14 +532,14 @@ abstract class BaseSdlManager { * * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out * - * @param rpcs is the list of RPCMessages being sent + * @param rpcs is the list of RPCMessages being sent * @param listener listener for updates and completions */ - public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener){ + public void sendSequentialRPCs(final List rpcs, final OnMultipleRequestListener listener) { List rpcRequestList = new ArrayList<>(); for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); + if (rpcs.get(i) instanceof RPCRequest) { + rpcRequestList.add((RPCRequest) rpcs.get(i)); } } @@ -514,51 +556,55 @@ abstract class BaseSdlManager { * * ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out * - * @param rpcs is the list of RPCMessages being sent + * @param rpcs is the list of RPCMessages being sent * @param listener listener for updates and completions */ public void sendRPCs(List rpcs, final OnMultipleRequestListener listener) { List rpcRequestList = new ArrayList<>(); for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); + if (rpcs.get(i) instanceof RPCRequest) { + rpcRequestList.add((RPCRequest) rpcs.get(i)); } } if (rpcRequestList.size() > 0) { - _internalInterface.sendRPCs(rpcRequestList,listener); + _internalInterface.sendRPCs(rpcRequestList, listener); } } /** * Add an OnRPCNotificationListener + * * @param listener listener that will be called when a notification is received */ - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - _internalInterface.addOnRPCNotificationListener(notificationId,listener); + public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + _internalInterface.addOnRPCNotificationListener(notificationId, listener); } /** * Remove an OnRPCNotificationListener + * * @param listener listener that was previously added */ - public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { _internalInterface.removeOnRPCNotificationListener(notificationId, listener); } /** * Add an OnRPCRequestListener + * * @param listener listener that will be called when a request is received */ - public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - _internalInterface.addOnRPCRequestListener(requestId,listener); + public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener) { + _internalInterface.addOnRPCRequestListener(requestId, listener); } /** * Remove an OnRPCRequestListener + * * @param listener listener that was previously added */ - public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener) { _internalInterface.removeOnRPCRequestListener(requestId, listener); } @@ -572,26 +618,30 @@ abstract class BaseSdlManager { setAppName(appName); setManagerListener(listener); } + /** * Sets the App ID + * * @param appId String representation of the App ID retreived from the SDL Developer Portal */ - public Builder setAppId(@NonNull final String appId){ + public Builder setAppId(@NonNull final String appId) { sdlManager.appId = appId; return this; } /** * Sets the Application Name + * * @param appName String that will be associated as the app's name */ - public Builder setAppName(@NonNull final String appName){ + public Builder setAppName(@NonNull final String appName) { sdlManager.appName = appName; return this; } /** * Sets the Short Application Name + * * @param shortAppName a shorter representation of the app's name for smaller displays */ public Builder setShortAppName(final String shortAppName) { @@ -603,6 +653,7 @@ abstract class BaseSdlManager { * Sets the minimum protocol version that will be permitted to connect. * If the protocol version of the head unit connected is below this version, * the app will disconnect with an EndService protocol message and will not register. + * * @param minimumProtocolVersion the minimum Protocol spec version that should be accepted */ public Builder setMinimumProtocolVersion(final Version minimumProtocolVersion) { @@ -613,6 +664,7 @@ abstract class BaseSdlManager { /** * The minimum RPC version that will be permitted to connect. * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. + * * @param minimumRPCVersion the minimum RPC spec version that should be accepted */ public Builder setMinimumRPCVersion(final Version minimumRPCVersion) { @@ -622,9 +674,10 @@ abstract class BaseSdlManager { /** * Sets the Language of the App + * * @param hmiLanguage the desired language to be used on the display/HMI of the connected module */ - public Builder setLanguage(final Language hmiLanguage){ + public Builder setLanguage(final Language hmiLanguage) { sdlManager.hmiLanguage = hmiLanguage; sdlManager.language = hmiLanguage; return this; @@ -632,30 +685,33 @@ abstract class BaseSdlManager { /** * Sets the TemplateColorScheme for daytime + * * @param dayColorScheme color scheme that will be used (if supported) when the display is in a "Day Mode" or * similar. Should comprise of colors that contrast well during the day under sunlight. */ - public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){ + public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme) { sdlManager.dayColorScheme = dayColorScheme; return this; } /** * Sets the TemplateColorScheme for nighttime + * * @param nightColorScheme color scheme that will be used (if supported) when the display is in a "Night Mode" * or similar. Should comprise of colors that contrast well during the night and are not * brighter than average. */ - public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){ + public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme) { sdlManager.nightColorScheme = nightColorScheme; return this; } /** * Sets the icon for the app on head unit / In-Vehicle-Infotainment system
+ * * @param sdlArtwork the icon that will be used to represent this application on the connected module */ - public Builder setAppIcon(final SdlArtwork sdlArtwork){ + public Builder setAppIcon(final SdlArtwork sdlArtwork) { sdlManager.appIcon = sdlArtwork; return this; } @@ -663,10 +719,11 @@ abstract class BaseSdlManager { /** * Sets the vector of AppHMIType
* Note: This should be an ordered list from most -> least relevant + * * @param hmiTypes HMI types that represent this application. For example, if the app is a music player, the * MEDIA HMIType should be included. */ - public Builder setAppTypes(final Vector hmiTypes){ + public Builder setAppTypes(final Vector hmiTypes) { sdlManager.hmiTypes = hmiTypes; if (hmiTypes != null) { @@ -680,15 +737,17 @@ abstract class BaseSdlManager { * Sets the FileManagerConfig for the session.
* Note: If not set, the default configuration value of 1 will be set for * artworkRetryCount and fileRetryCount in FileManagerConfig + * * @param fileManagerConfig - configuration options */ - public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){ + public Builder setFileManagerConfig(final FileManagerConfig fileManagerConfig) { sdlManager.fileManagerConfig = fileManagerConfig; return this; } /** * Sets the voice recognition synonyms that can be used to identify this application. + * * @param vrSynonyms a vector of Strings that can be associated with this app. For example the app's name should * be included as well as any phonetic spellings of the app name that might help the on-board * VR system associated a users spoken word with the supplied synonyms. @@ -701,6 +760,7 @@ abstract class BaseSdlManager { /** * Sets the Text-To-Speech Name of the application. These TTSChunks might be used by the module as an audio * representation of the app's name. + * * @param ttsChunks the TTS chunks that can represent this app's name */ public Builder setTtsName(final Vector ttsChunks) { @@ -711,15 +771,17 @@ abstract class BaseSdlManager { /** * This Object type may change with the transport refactor * Sets the BaseTransportConfig + * * @param transport the type of transport that should be used for this SdlManager instance. */ - public Builder setTransportType(@NonNull BaseTransportConfig transport){ + public Builder setTransportType(@NonNull BaseTransportConfig transport) { sdlManager.transport = transport; return this; } /** * Sets the Security libraries + * * @param secList The list of security class(es) */ @Deprecated @@ -730,7 +792,8 @@ abstract class BaseSdlManager { /** * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) + * + * @param secList The list of security class(es) * @param listener The callback object */ public Builder setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { @@ -741,19 +804,21 @@ abstract class BaseSdlManager { /** * Set the SdlManager Listener + * * @param listener the listener */ - public Builder setManagerListener(@NonNull final SdlManagerListener listener){ + public Builder setManagerListener(@NonNull final SdlManagerListener listener) { sdlManager.managerListener = listener; return this; } /** * Set RPCNotification listeners. SdlManager will preload these listeners before any RPCs are sent/received. + * * @param listeners a map of listeners that will be called when a notification is received. - * Key represents the FunctionID of the notification and value represents the listener + * Key represents the FunctionID of the notification and value represents the listener */ - public Builder setRPCNotificationListeners(Map listeners){ + public Builder setRPCNotificationListeners(Map listeners) { sdlManager.onRPCNotificationListeners = listeners; return this; } @@ -777,21 +842,21 @@ abstract class BaseSdlManager { sdlManager.hmiTypes = hmiTypesDefault; sdlManager.isMediaApp = false; } - if(sdlManager.fileManagerConfig == null){ + if (sdlManager.fileManagerConfig == null) { //if FileManagerConfig is not set use default sdlManager.fileManagerConfig = new FileManagerConfig(); } - if (sdlManager.hmiLanguage == null){ + if (sdlManager.hmiLanguage == null) { sdlManager.hmiLanguage = Language.EN_US; sdlManager.language = Language.EN_US; } - if (sdlManager.minimumProtocolVersion == null){ + if (sdlManager.minimumProtocolVersion == null) { sdlManager.minimumProtocolVersion = new Version("1.0.0"); } - if (sdlManager.minimumRPCVersion == null){ + if (sdlManager.minimumRPCVersion == null) { sdlManager.minimumRPCVersion = new Version("1.0.0"); } 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 4a12c18c1..0054b7810 100644 --- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseLifecycleManager.java @@ -111,7 +111,7 @@ abstract class BaseLifecycleManager { UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530; // Sdl Synchronization Objects - private static final Object RPC_LISTENER_LOCK = new Object(), + private static final Object RPC_LISTENER_LOCK = new Object(), ON_UPDATE_LISTENER_LOCK = new Object(), ON_REQUEST_LISTENER_LOCK = new Object(), ON_NOTIFICATION_LISTENER_LOCK = new Object(); @@ -135,7 +135,7 @@ abstract class BaseLifecycleManager { Version minimumRPCVersion; BaseTransportConfig _transportConfig; - BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener){ + BaseLifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { this.appConfig = appConfig; this._transportConfig = config; this.lifecycleListener = listener; @@ -144,7 +144,7 @@ abstract class BaseLifecycleManager { initializeProxy(); } - public void start(){ + public void start() { try { session.startSession(); } catch (SdlException e) { @@ -161,7 +161,7 @@ abstract class BaseLifecycleManager { } } - public void stop(){ + public void stop() { session.close(); } @@ -172,11 +172,11 @@ abstract class BaseLifecycleManager { return new Version(1, 0, 0); } - private void sendRPCs(List messages, final OnMultipleRequestListener listener){ - if(messages != null ){ - for(RPCMessage message : messages){ + private void sendRPCs(List messages, final OnMultipleRequestListener listener) { + if (messages != null) { + for (RPCMessage message : messages) { // Request Specifics - if(message instanceof RPCRequest){ + if (message instanceof RPCRequest) { RPCRequest request = ((RPCRequest) message); final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); request.setCorrelationID(CorrelationIdGenerator.generateId()); @@ -185,7 +185,7 @@ abstract class BaseLifecycleManager { request.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { - if (devOnRPCResponseListener != null){ + if (devOnRPCResponseListener != null) { devOnRPCResponseListener.onResponse(correlationId, response); } if (listener.getSingleRpcResponseListener() != null) { @@ -196,7 +196,7 @@ abstract class BaseLifecycleManager { @Override public void onError(int correlationId, Result resultCode, String info) { super.onError(correlationId, resultCode, info); - if (devOnRPCResponseListener != null){ + if (devOnRPCResponseListener != null) { devOnRPCResponseListener.onError(correlationId, resultCode, info); } if (listener.getSingleRpcResponseListener() != null) { @@ -206,12 +206,12 @@ abstract class BaseLifecycleManager { }); } sendRPCMessagePrivate(request, false); - }else { + } else { // Notifications and Responses sendRPCMessagePrivate(message, false); - if (listener != null){ + if (listener != null) { listener.onUpdate(messages.size()); - if (messages.size() == 0){ + if (messages.size() == 0) { listener.onFinished(); } } @@ -220,11 +220,11 @@ abstract class BaseLifecycleManager { } } - private void sendSequentialRPCs(final List messages, final OnMultipleRequestListener listener){ - if (messages != null){ + private void sendSequentialRPCs(final List messages, final OnMultipleRequestListener listener) { + if (messages != null) { // Break out of recursion, we have finished the requests if (messages.size() == 0) { - if(listener != null){ + if (listener != null) { listener.onFinished(); } return; @@ -242,7 +242,7 @@ abstract class BaseLifecycleManager { request.setOnRPCResponseListener(new OnRPCResponseListener() { @Override public void onResponse(int correlationId, RPCResponse response) { - if (devOnRPCResponseListener != null){ + if (devOnRPCResponseListener != null) { devOnRPCResponseListener.onResponse(correlationId, response); } if (listener != null) { @@ -255,7 +255,7 @@ abstract class BaseLifecycleManager { @Override public void onError(int correlationId, Result resultCode, String info) { - if (devOnRPCResponseListener != null){ + if (devOnRPCResponseListener != null) { devOnRPCResponseListener.onError(correlationId, resultCode, info); } if (listener != null) { @@ -290,17 +290,17 @@ abstract class BaseLifecycleManager { * @return the system capability manager. */ @RestrictTo(RestrictTo.Scope.LIBRARY) - public SystemCapabilityManager getSystemCapabilityManager(SdlManager sdlManager){ - if(sdlManager != null){ + public SystemCapabilityManager getSystemCapabilityManager(SdlManager sdlManager) { + if (sdlManager != null) { return systemCapabilityManager; } return null; } - private boolean isConnected(){ - if(session != null){ + private boolean isConnected() { + if (session != null) { return session.getIsConnected(); - }else{ + } else { return false; } } @@ -313,22 +313,23 @@ abstract class BaseLifecycleManager { * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet * registered with the module. */ - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { return this.raiResponse; } /** * Get the current OnHMIStatus + * * @return OnHMIStatus object represents the current OnHMIStatus */ public OnHMIStatus getCurrentHMIStatus() { return currentHMIStatus; } - void onClose(String info, Exception e){ + void onClose(String info, Exception e) { Log.i(TAG, "onClose"); - if(lifecycleListener != null){ - lifecycleListener.onProxyClosed((LifecycleManager) this, info,e,null); + if (lifecycleListener != null) { + lifecycleListener.onProxyClosed((LifecycleManager) this, info, e, null); } } @@ -351,7 +352,7 @@ abstract class BaseLifecycleManager { ********************************** INTERNAL - RPC LISTENERS !! START !! ********************************* *********************************************************************************************************/ - private void setupInternalRpcListeners(){ + private void setupInternalRpcListeners() { addRpcListener(FunctionID.REGISTER_APP_INTERFACE, rpcListener); addRpcListener(FunctionID.ON_HMI_STATUS, rpcListener); addRpcListener(FunctionID.ON_HASH_CHANGE, rpcListener); @@ -413,7 +414,7 @@ abstract class BaseLifecycleManager { } }; handleOffboardTransmissionThread.start(); - }else if (onSystemRequest.getRequestType() == RequestType.ICON_URL && onSystemRequest.getUrl() != null) { + } else if (onSystemRequest.getRequestType() == RequestType.ICON_URL && onSystemRequest.getUrl() != null) { //Download the icon file and send SystemRequest RPC Thread handleOffBoardTransmissionThread = new Thread() { @Override @@ -443,7 +444,7 @@ abstract class BaseLifecycleManager { if (!onAppInterfaceUnregistered.getReason().equals(AppInterfaceUnregisteredReason.LANGUAGE_CHANGE)) { Log.v(TAG, "on app interface unregistered"); cleanProxy(); - }else{ + } else { Log.v(TAG, "re-registering for language change"); processLanguageChange(); } @@ -457,10 +458,9 @@ abstract class BaseLifecycleManager { } - }; - private void processLanguageChange(){ + private void processLanguageChange() { if (session != null) { if (session.getIsConnected()) { session.close(); @@ -482,15 +482,15 @@ abstract class BaseLifecycleManager { ********************************** METHODS - RPC LISTENERS !! START !! ********************************** *********************************************************************************************************/ - private boolean onRPCReceived(final RPCMessage message){ - synchronized(RPC_LISTENER_LOCK){ - if(message == null || message.getFunctionID() == null){ + private boolean onRPCReceived(final RPCMessage message) { + synchronized (RPC_LISTENER_LOCK) { + if (message == null || message.getFunctionID() == null) { return false; } final int id = message.getFunctionID().getId(); CopyOnWriteArrayList listeners = rpcListeners.get(id); - if(listeners!=null && listeners.size()>0) { + if (listeners != null && listeners.size() > 0) { for (OnRPCListener listener : listeners) { listener.onReceived(message); } @@ -500,8 +500,8 @@ abstract class BaseLifecycleManager { } } - private void addRpcListener(FunctionID id, OnRPCListener listener){ - synchronized(RPC_LISTENER_LOCK){ + private void addRpcListener(FunctionID id, OnRPCListener listener) { + synchronized (RPC_LISTENER_LOCK) { if (id != null && listener != null) { if (!rpcListeners.containsKey(id.getId())) { rpcListeners.put(id.getId(), new CopyOnWriteArrayList()); @@ -512,12 +512,12 @@ abstract class BaseLifecycleManager { } } - private boolean removeOnRPCListener(FunctionID id, OnRPCListener listener){ - synchronized(RPC_LISTENER_LOCK){ - if(rpcListeners!= null + private boolean removeOnRPCListener(FunctionID id, OnRPCListener listener) { + synchronized (RPC_LISTENER_LOCK) { + if (rpcListeners != null && id != null && listener != null - && rpcListeners.containsKey(id.getId())){ + && rpcListeners.containsKey(id.getId())) { return rpcListeners.get(id.getId()).remove(listener); } } @@ -526,16 +526,17 @@ abstract class BaseLifecycleManager { /** * Only call this method for a PutFile response. It will cause a class cast exception if not. + * * @param correlationId correlation id of the packet being updated - * @param bytesWritten how many bytes were written - * @param totalSize the total size in bytes + * @param bytesWritten how many bytes were written + * @param totalSize the total size in bytes */ @SuppressWarnings("unused") - private void onPacketProgress(int correlationId, long bytesWritten, long totalSize){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - if(rpcResponseListeners !=null - && rpcResponseListeners.containsKey(correlationId)){ - ((OnPutFileUpdateListener)rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize); + private void onPacketProgress(int correlationId, long bytesWritten, long totalSize) { + synchronized (ON_UPDATE_LISTENER_LOCK) { + if (rpcResponseListeners != null + && rpcResponseListeners.containsKey(correlationId)) { + ((OnPutFileUpdateListener) rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize); } } @@ -544,19 +545,20 @@ abstract class BaseLifecycleManager { /** * Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code, *

Will automatically remove the listener for the list of listeners on completion. + * * @param msg The RPCResponse message that was received * @return if a listener was called or not */ @SuppressWarnings("UnusedReturnValue") - private boolean onRPCResponseReceived(RPCResponse msg){ - synchronized(ON_UPDATE_LISTENER_LOCK){ + private boolean onRPCResponseReceived(RPCResponse msg) { + synchronized (ON_UPDATE_LISTENER_LOCK) { int correlationId = msg.getCorrelationID(); - if(rpcResponseListeners !=null - && rpcResponseListeners.containsKey(correlationId)){ + if (rpcResponseListeners != null + && rpcResponseListeners.containsKey(correlationId)) { OnRPCResponseListener listener = rpcResponseListeners.get(correlationId); - if(msg.getSuccess()){ + if (msg.getSuccess()) { listener.onResponse(correlationId, msg); - }else{ + } else { listener.onError(correlationId, msg.getResultCode(), msg.getInfo()); } rpcResponseListeners.remove(correlationId); @@ -568,16 +570,17 @@ abstract class BaseLifecycleManager { /** * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id - * @param listener that will get called back when a response is received + * + * @param listener that will get called back when a response is received * @param correlationId of the RPCRequest that was sent - * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored. + * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored. */ - private void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){ - synchronized(ON_UPDATE_LISTENER_LOCK){ - if(rpcResponseListeners!=null - && listener !=null){ - if(listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE){ - ((OnPutFileUpdateListener)listener).setTotalSize(totalSize); + private void addOnRPCResponseListener(OnRPCResponseListener listener, int correlationId, int totalSize) { + synchronized (ON_UPDATE_LISTENER_LOCK) { + if (rpcResponseListeners != null + && listener != null) { + if (listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE) { + ((OnPutFileUpdateListener) listener).setTotalSize(totalSize); } listener.onStart(correlationId); rpcResponseListeners.put(correlationId, listener); @@ -586,8 +589,8 @@ abstract class BaseLifecycleManager { } @SuppressWarnings("unused") - private HashMap getResponseListeners(){ - synchronized(ON_UPDATE_LISTENER_LOCK){ + private HashMap getResponseListeners() { + synchronized (ON_UPDATE_LISTENER_LOCK) { return this.rpcResponseListeners; } } @@ -595,22 +598,23 @@ abstract class BaseLifecycleManager { /** * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC * service from the module. For example, this should be used to login to a user account. + * * @return the string representation of the auth token */ - public String getAuthToken(){ + public String getAuthToken() { return this.authToken; } @SuppressWarnings("UnusedReturnValue") - private boolean onRPCNotificationReceived(RPCNotification notification){ - if(notification == null){ + private boolean onRPCNotificationReceived(RPCNotification notification) { + if (notification == null) { DebugTool.logError("onRPCNotificationReceived - Notification was null"); return false; } - DebugTool.logInfo("onRPCNotificationReceived - " + notification.getFunctionName() ); + DebugTool.logInfo("onRPCNotificationReceived - " + notification.getFunctionName()); //Before updating any listeners, make sure to do any final updates to the notification RPC now - if(FunctionID.ON_HMI_STATUS.toString().equals(notification.getFunctionName())){ + if (FunctionID.ON_HMI_STATUS.toString().equals(notification.getFunctionName())) { OnHMIStatus onHMIStatus = (OnHMIStatus) notification; onHMIStatus.setFirstRun(firstTimeFull); if (onHMIStatus.getHmiLevel() == HMILevel.HMI_FULL) { @@ -618,9 +622,9 @@ abstract class BaseLifecycleManager { } } - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + synchronized (ON_NOTIFICATION_LISTENER_LOCK) { CopyOnWriteArrayList listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName())); - if(listeners!=null && listeners.size()>0) { + if (listeners != null && listeners.size() > 0) { for (OnRPCNotificationListener listener : listeners) { listener.onNotified(notification); } @@ -633,27 +637,28 @@ abstract class BaseLifecycleManager { /** * This will add a listener for the specific type of notification. As of now it will only allow * a single listener per notification function id + * * @param notificationId The notification type that this listener is designated for - * @param listener The listener that will be called when a notification of the provided type is received + * @param listener The listener that will be called when a notification of the provided type is received */ @SuppressWarnings("unused") - private void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ - if(notificationId != null && listener != null){ - if(!rpcNotificationListeners.containsKey(notificationId.getId())){ - rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList()); + private void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + synchronized (ON_NOTIFICATION_LISTENER_LOCK) { + if (notificationId != null && listener != null) { + if (!rpcNotificationListeners.containsKey(notificationId.getId())) { + rpcNotificationListeners.put(notificationId.getId(), new CopyOnWriteArrayList()); } rpcNotificationListeners.get(notificationId.getId()).add(listener); } } } - private boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - synchronized(ON_NOTIFICATION_LISTENER_LOCK){ - if(rpcNotificationListeners!= null + private boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + synchronized (ON_NOTIFICATION_LISTENER_LOCK) { + if (rpcNotificationListeners != null && notificationId != null && listener != null - && rpcNotificationListeners.containsKey(notificationId.getId())){ + && rpcNotificationListeners.containsKey(notificationId.getId())) { return rpcNotificationListeners.get(notificationId.getId()).remove(listener); } } @@ -661,16 +666,16 @@ abstract class BaseLifecycleManager { } @SuppressWarnings("UnusedReturnValue") - private boolean onRPCRequestReceived(RPCRequest request){ - if(request == null){ + private boolean onRPCRequestReceived(RPCRequest request) { + if (request == null) { DebugTool.logError("onRPCRequestReceived - request was null"); return false; } - DebugTool.logInfo("onRPCRequestReceived - " + request.getFunctionName() ); + DebugTool.logInfo("onRPCRequestReceived - " + request.getFunctionName()); - synchronized(ON_REQUEST_LISTENER_LOCK){ + synchronized (ON_REQUEST_LISTENER_LOCK) { CopyOnWriteArrayList listeners = rpcRequestListeners.get(FunctionID.getFunctionId(request.getFunctionName())); - if(listeners!=null && listeners.size()>0) { + if (listeners != null && listeners.size() > 0) { for (OnRPCRequestListener listener : listeners) { listener.onRequest(request); } @@ -683,15 +688,16 @@ abstract class BaseLifecycleManager { /** * This will add a listener for the specific type of request. As of now it will only allow * a single listener per request function id + * * @param requestId The request type that this listener is designated for - * @param listener The listener that will be called when a request of the provided type is received + * @param listener The listener that will be called when a request of the provided type is received */ @SuppressWarnings("unused") - private void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - synchronized(ON_REQUEST_LISTENER_LOCK){ - if(requestId != null && listener != null){ - if(!rpcRequestListeners.containsKey(requestId.getId())){ - rpcRequestListeners.put(requestId.getId(),new CopyOnWriteArrayList()); + private void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener) { + synchronized (ON_REQUEST_LISTENER_LOCK) { + if (requestId != null && listener != null) { + if (!rpcRequestListeners.containsKey(requestId.getId())) { + rpcRequestListeners.put(requestId.getId(), new CopyOnWriteArrayList()); } rpcRequestListeners.get(requestId.getId()).add(listener); } @@ -699,12 +705,12 @@ abstract class BaseLifecycleManager { } @SuppressWarnings("UnusedReturnValue") - private boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - synchronized(ON_REQUEST_LISTENER_LOCK){ - if(rpcRequestListeners!= null + private boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener) { + synchronized (ON_REQUEST_LISTENER_LOCK) { + if (rpcRequestListeners != null && requestId != null && listener != null - && rpcRequestListeners.containsKey(requestId.getId())){ + && rpcRequestListeners.containsKey(requestId.getId())) { return rpcRequestListeners.get(requestId.getId()).remove(listener); } } @@ -715,7 +721,7 @@ abstract class BaseLifecycleManager { **************************************** RPC LISTENERS !! END !! **************************************** *********************************************************************************************************/ - private void sendRPCMessagePrivate(RPCMessage message, boolean isInternalMessage){ + private void sendRPCMessagePrivate(RPCMessage message, boolean isInternalMessage) { try { if (!isInternalMessage && message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { RPCRequest request = (RPCRequest) message; @@ -741,7 +747,7 @@ abstract class BaseLifecycleManager { //FIXME this is temporary until the next major release of the library where OK is removed if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { RPCRequest request = (RPCRequest) message; - if(FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) + if (FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) || FunctionID.UNSUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) || FunctionID.BUTTON_PRESS.toString().equals(request.getFunctionName())) { @@ -768,12 +774,12 @@ abstract class BaseLifecycleManager { } } - message.format(rpcSpecVersion,true); - byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor()); + message.format(rpcSpecVersion, true); + byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte) getProtocolVersion().getMajor()); final ProtocolMessage pm = new ProtocolMessage(); pm.setData(msgBytes); - if (session != null){ + if (session != null) { pm.setSessionID(session.getSessionId()); } @@ -786,36 +792,36 @@ abstract class BaseLifecycleManager { } else { pm.setPayloadProtected(message.isPayloadProtected()); } - if (pm.getPayloadProtected() && (encryptionLifecycleManager == null || !encryptionLifecycleManager.isEncryptionReady())){ + if (pm.getPayloadProtected() && (encryptionLifecycleManager == null || !encryptionLifecycleManager.isEncryptionReady())) { String errorInfo = "Trying to send an encrypted message and there is no secured service"; if (message.getMessageType().equals((RPCMessage.KEY_REQUEST))) { RPCRequest request = (RPCRequest) message; OnRPCResponseListener listener = ((RPCRequest) message).getOnRPCResponseListener(); if (listener != null) { - listener.onError(request.getCorrelationID(), Result.ABORTED, errorInfo); + listener.onError(request.getCorrelationID(), Result.ABORTED, errorInfo); } } DebugTool.logWarning(errorInfo); return; } - if(RPCMessage.KEY_REQUEST.equals(message.getMessageType())){ // Request Specifics - pm.setRPCType((byte)0x00); - Integer corrId = ((RPCRequest)message).getCorrelationID(); - if( corrId== null) { + if (RPCMessage.KEY_REQUEST.equals(message.getMessageType())) { // Request Specifics + pm.setRPCType((byte) 0x00); + Integer corrId = ((RPCRequest) message).getCorrelationID(); + if (corrId == null) { Log.e(TAG, "No correlation ID attached to request. Not sending"); return; - }else{ + } else { pm.setCorrID(corrId); - OnRPCResponseListener listener = ((RPCRequest)message).getOnRPCResponseListener(); - if(listener != null){ + OnRPCResponseListener listener = ((RPCRequest) message).getOnRPCResponseListener(); + if (listener != null) { addOnRPCResponseListener(listener, corrId, msgBytes.length); } } - }else if (RPCMessage.KEY_RESPONSE.equals(message.getMessageType())){ // Response Specifics + } else if (RPCMessage.KEY_RESPONSE.equals(message.getMessageType())) { // Response Specifics RPCResponse response = (RPCResponse) message; - pm.setRPCType((byte)0x01); + pm.setRPCType((byte) 0x01); if (response.getCorrelationID() == null) { //Log error here //throw new SdlException("CorrelationID cannot be null. RPC: " + response.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT); @@ -824,15 +830,15 @@ abstract class BaseLifecycleManager { } else { pm.setCorrID(response.getCorrelationID()); } - }else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics - pm.setRPCType((byte)0x02); + } else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics + pm.setRPCType((byte) 0x02); } - if (message.getBulkData() != null){ + if (message.getBulkData() != null) { pm.setBulkData(message.getBulkData()); } - if(message.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())){ + if (message.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())) { pm.setPriorityCoefficient(1); } @@ -889,7 +895,7 @@ abstract class BaseLifecycleManager { FunctionID functionID = rpc.getFunctionID(); if (functionID != null && (functionID.equals(FunctionID.ON_BUTTON_PRESS)) || functionID.equals(FunctionID.ON_BUTTON_EVENT)) { RPCNotification notificationCompat = handleButtonNotificationFormatting(rpc); - if(notificationCompat != null){ + if (notificationCompat != null) { onRPCNotificationReceived((notificationCompat)); } } @@ -1159,15 +1165,19 @@ abstract class BaseLifecycleManager { ********************************************* ISdl - END ************************************************ *********************************************************************************************************/ - public interface LifecycleListener{ + public interface LifecycleListener { void onProxyConnected(LifecycleManager lifeCycleManager); + void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason); + void onServiceStarted(SessionType sessionType); + void onServiceEnded(SessionType sessionType); + void onError(LifecycleManager lifeCycleManager, String info, Exception e); } - public static class AppConfig{ + public static class AppConfig { private String appID, appName, ngnMediaScreenAppName; private Vector ttsName; private Vector vrSynonyms; @@ -1178,7 +1188,7 @@ abstract class BaseLifecycleManager { private Version minimumProtocolVersion; private Version minimumRPCVersion; - private void prepare(){ + private void prepare() { if (getNgnMediaScreenAppName() == null) { setNgnMediaScreenAppName(getAppName()); } @@ -1318,22 +1328,23 @@ abstract class BaseLifecycleManager { /** * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old * OK button name. This should be removed during the next major release + * * @param notification an RPC message object that should be either an ON_BUTTON_EVENT or ON_BUTTON_PRESS otherwise * it will be ignored */ - private RPCNotification handleButtonNotificationFormatting(RPCMessage notification){ - if(FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName()) - || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())){ + private RPCNotification handleButtonNotificationFormatting(RPCMessage notification) { + if (FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName()) + || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())) { - ButtonName buttonName = (ButtonName)notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME); + ButtonName buttonName = (ButtonName) notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME); ButtonName compatBtnName = null; - if(rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5){ - if(ButtonName.PLAY_PAUSE.equals(buttonName)){ - compatBtnName = ButtonName.OK; + if (rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5) { + if (ButtonName.PLAY_PAUSE.equals(buttonName)) { + compatBtnName = ButtonName.OK; } - }else{ // rpc spec version is either null or less than 5 - if(ButtonName.OK.equals(buttonName)){ + } else { // rpc spec version is either null or less than 5 + if (ButtonName.OK.equals(buttonName)) { compatBtnName = ButtonName.PLAY_PAUSE; } } @@ -1360,14 +1371,14 @@ abstract class BaseLifecycleManager { notification2.setParameters(OnButtonEvent.KEY_BUTTON_NAME, compatBtnName); return notification2; } - }catch (Exception e){ + } catch (Exception e) { //Should never get here } } return null; } - void cleanProxy(){ + void cleanProxy() { firstTimeFull = true; currentHMIStatus = null; if (rpcListeners != null) { @@ -1385,7 +1396,7 @@ abstract class BaseLifecycleManager { if (session != null && session.getIsConnected()) { session.close(); } - if (encryptionLifecycleManager != null){ + if (encryptionLifecycleManager != null) { encryptionLifecycleManager.dispose(); } } @@ -1397,7 +1408,8 @@ abstract class BaseLifecycleManager { /** * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) + * + * @param secList The list of security class(es) * @param listener The callback object */ public void setSdlSecurity(@NonNull List> secList, ServiceEncryptionListener listener) { @@ -1446,7 +1458,7 @@ abstract class BaseLifecycleManager { ********************************** Platform specific methods - START ************************************* *********************************************************************************************************/ - void initializeProxy(){ + void initializeProxy() { this.rpcListeners = new HashMap<>(); this.rpcResponseListeners = new HashMap<>(); this.rpcNotificationListeners = new HashMap<>(); @@ -1455,7 +1467,7 @@ abstract class BaseLifecycleManager { setupInternalRpcListeners(); } - void onProtocolSessionStarted (SessionType sessionType) { + void onProtocolSessionStarted(SessionType sessionType) { if (sessionType != null) { if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1) { Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion())); @@ -1497,23 +1509,34 @@ abstract class BaseLifecycleManager { } } - void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) {} + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { + } - void onProtocolSessionStartedNACKed (SessionType sessionType) {} + void onProtocolSessionStartedNACKed(SessionType sessionType) { + } - void onProtocolSessionEnded (SessionType sessionType) {} + void onProtocolSessionEnded(SessionType sessionType) { + } - void onProtocolSessionEndedNACKed (SessionType sessionType) {} + void onProtocolSessionEndedNACKed(SessionType sessionType) { + } - void startVideoService(boolean encrypted, VideoStreamingParameters parameters) {} + void startVideoService(boolean encrypted, VideoStreamingParameters parameters) { + } - boolean endVideoStream() { return false; } + boolean endVideoStream() { + return false; + } - void startAudioService(boolean encrypted) {} + void startAudioService(boolean encrypted) { + } - boolean endAudioStream() { return false; } + boolean endAudioStream() { + return false; + } - void setSdlSecurityStaticVars() {} + void setSdlSecurityStaticVars() { + } /* ******************************************************************************************************* ********************************** Platform specific methods - End ************************************* diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java index cdb42dd7b..a711438cc 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -44,11 +44,11 @@ import com.smartdevicelink.util.DebugTool; /** * SDLManager
- * + *

* This is the main point of contact between an application and SDL
- * + *

* It is broken down to these areas:
- * + *

* 1. SDLManagerBuilder
* 2. ISdl Interface along with its overridden methods - This can be passed into attached managers
* 3. Sending Requests
@@ -80,7 +80,7 @@ public class SdlManager extends BaseSdlManager { } @Override - protected void initialize(){ + protected void initialize() { // Instantiate sub managers this.permissionManager = new PermissionManager(_internalInterface); this.fileManager = new FileManager(_internalInterface, fileManagerConfig); @@ -94,14 +94,14 @@ 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 != null && fileManager != null && screenManager != null) { + if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.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) { String info = "ERROR starting sdl manager, all sub managers are in error state"; Log.e(TAG, info); transitionToState(BaseSubManager.ERROR); @@ -128,8 +128,8 @@ public class SdlManager extends BaseSdlManager { private void notifyDevListener(String info) { if (managerListener != null) { - if (getState() == BaseSubManager.ERROR){ - managerListener.onError((SdlManager)this, info, null); + if (getState() == BaseSubManager.ERROR) { + managerListener.onError((SdlManager) this, info, null); } else { managerListener.onStart((SdlManager) this); } @@ -143,8 +143,8 @@ public class SdlManager extends BaseSdlManager { @Override void onProxyClosed(SdlDisconnectedReason reason) { - Log.i(TAG,"Proxy is closed."); - if(managerListener != null){ + Log.i(TAG, "Proxy is closed."); + if (managerListener != null) { managerListener.onDestroy(SdlManager.this); } } @@ -167,8 +167,8 @@ public class SdlManager extends BaseSdlManager { this.lifecycleManager.stop(); } - if(managerListener != null){ - managerListener.onDestroy((SdlManager)this); + if (managerListener != null) { + managerListener.onDestroy((SdlManager) this); managerListener = null; } @@ -179,11 +179,12 @@ public class SdlManager extends BaseSdlManager { public static class Builder extends BaseSdlManager.Builder { /** * Builder for the SdlManager. Parameters in the constructor are required. - * @param appId the app's ID - * @param appName the app's name + * + * @param appId the app's ID + * @param appName the app's name * @param listener a SdlManagerListener object */ - public Builder(@NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ + public Builder(@NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener) { super(appId, appName, listener); } } -- cgit v1.2.1