summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilal Alsharifi <bilal.alsharifi@gmail.com>2019-03-04 14:42:53 -0500
committerBilal Alsharifi <bilal.alsharifi@gmail.com>2019-03-04 14:42:53 -0500
commitc562bb19d4727656e047c7223e376a01bce8cca6 (patch)
tree9847476edf250502ddf6d488c763c7c5a8badf8c
parent1db257635bfedd22009b814b2f867598178c106c (diff)
downloadsdl_android-c562bb19d4727656e047c7223e376a01bce8cca6.tar.gz
Add javaSE project
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java7
-rw-r--r--javaSE/build.gradle37
-rw-r--r--javaSE/gradle/wrapper/gradle-wrapper.jarbin0 -> 55190 bytes
-rw-r--r--javaSE/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xjavaSE/gradlew172
-rw-r--r--javaSE/gradlew.bat84
-rw-r--r--javaSE/libs/bson_java_lib.jarbin0 -> 36302 bytes
-rw-r--r--javaSE/settings.gradle2
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java1114
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java21
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/file/FileManager.java108
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java83
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java114
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java1182
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/permission/PermissionManager.java24
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/screen/ScreenManager.java18
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/screen/SoftButtonManager.java24
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java32
-rw-r--r--javaSE/src/main/java/com/smartdevicelink/security/SdlSecurityBase.java5
-rw-r--r--javaSE/src/main/java/hello_sdl/Main.java186
20 files changed, 3215 insertions, 4 deletions
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java
index 746129a85..29b7387cc 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/RegisterAppInterfaceResponse.java
@@ -4,7 +4,6 @@ import android.support.annotation.NonNull;
import com.smartdevicelink.protocol.enums.FunctionID;
import com.smartdevicelink.proxy.RPCResponse;
-import com.smartdevicelink.proxy.Version;
import com.smartdevicelink.proxy.rpc.enums.ButtonName;
import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities;
import com.smartdevicelink.proxy.rpc.enums.Language;
@@ -369,9 +368,9 @@ public class RegisterAppInterfaceResponse extends RPCResponse {
setParameters(KEY_PCM_STREAM_CAPABILITIES, pcmStreamingCapabilities);
}
public String getProxyVersionInfo() {
- if (Version.VERSION != null)
- return Version.VERSION;
-
+ /*FIXME if (Version.VERSION != null)
+ return Version.VERSION;*/
+
return null;
}
public void setSupportedDiagModes(List<Integer> supportedDiagModes) {
diff --git a/javaSE/build.gradle b/javaSE/build.gradle
new file mode 100644
index 000000000..264be4bf6
--- /dev/null
+++ b/javaSE/build.gradle
@@ -0,0 +1,37 @@
+plugins {
+ id 'java-library'
+}
+
+group 'com.smartdevicelink'
+version '1.0'
+
+sourceCompatibility = 1.8
+
+repositories {
+ google()
+ jcenter()
+}
+
+// This extraLibs solution is explained here: https://discuss.gradle.org/t/how-to-include-dependencies-in-jar/19571/5
+configurations {
+ // configuration that holds jars to include in the jar
+ extraLibs
+}
+
+dependencies {
+ extraLibs fileTree(dir: 'libs', include: ['*.jar'])
+ extraLibs 'com.android.support:support-annotations:28.0.0'
+ extraLibs 'org.java-websocket:Java-WebSocket:1.3.9'
+ configurations.api.extendsFrom(configurations.extraLibs)
+}
+
+sourceSets {
+ main.java.srcDirs += '../base/src/main/java'
+}
+
+jar {
+ from {
+ configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
+ }
+}
+
diff --git a/javaSE/gradle/wrapper/gradle-wrapper.jar b/javaSE/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..87b738cbd
--- /dev/null
+++ b/javaSE/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/javaSE/gradle/wrapper/gradle-wrapper.properties b/javaSE/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..ca21d83d3
--- /dev/null
+++ b/javaSE/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jan 25 17:44:56 EST 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/javaSE/gradlew b/javaSE/gradlew
new file mode 100755
index 000000000..af6708ff2
--- /dev/null
+++ b/javaSE/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/javaSE/gradlew.bat b/javaSE/gradlew.bat
new file mode 100644
index 000000000..0f8d5937c
--- /dev/null
+++ b/javaSE/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/javaSE/libs/bson_java_lib.jar b/javaSE/libs/bson_java_lib.jar
new file mode 100644
index 000000000..0a6e6500e
--- /dev/null
+++ b/javaSE/libs/bson_java_lib.jar
Binary files differ
diff --git a/javaSE/settings.gradle b/javaSE/settings.gradle
new file mode 100644
index 000000000..f7ac48020
--- /dev/null
+++ b/javaSE/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'javaSE'
+
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java
new file mode 100644
index 000000000..8d3791b94
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManager.java
@@ -0,0 +1,1114 @@
+package com.smartdevicelink.managers;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+import com.smartdevicelink.exception.SdlException;
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
+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.RPCStreamController;
+import com.smartdevicelink.proxy.SystemCapabilityManager;
+import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
+import com.smartdevicelink.proxy.callbacks.OnServiceNACKed;
+import com.smartdevicelink.proxy.interfaces.*;
+import com.smartdevicelink.proxy.rpc.*;
+import com.smartdevicelink.proxy.rpc.enums.*;
+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.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.WebSocketServerConfig;
+import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.util.DebugTool;
+import com.smartdevicelink.util.Version;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * <strong>SDLManager</strong> <br>
+ *
+ * This is the main point of contact between an application and SDL <br>
+ *
+ * It is broken down to these areas: <br>
+ *
+ * 1. SDLManagerBuilder <br>
+ * 2. ISdl Interface along with its overridden methods - This can be passed into attached managers <br>
+ * 3. Sending Requests <br>
+ * 4. Helper methods
+ */
+public class SdlManager extends BaseSdlManager{
+
+ private static final String TAG = "SdlManager";
+ private LifecycleManager proxy;
+ private String appId, appName, shortAppName;
+ private boolean isMediaApp;
+ private Language hmiLanguage;
+ private SdlArtwork appIcon;
+ private Vector<AppHMIType> hmiTypes;
+ private BaseTransportConfig transport;
+ //FIXME private Context context;
+ private Vector<String> vrSynonyms;
+ private Vector<TTSChunk> ttsChunks;
+ private TemplateColorScheme dayColorScheme, nightColorScheme;
+ private SdlManagerListener managerListener;
+ private int state = -1;
+ private List<Class<? extends SdlSecurityBase>> sdlSecList;
+ //FIXME private LockScreenConfig lockScreenConfig;
+ private final Object STATE_LOCK = new Object();
+
+
+ // Managers
+ private PermissionManager permissionManager;
+ private FileManager fileManager;
+ //private LockScreenManager lockScreenManager;
+ private ScreenManager screenManager;
+ //private VideoStreamManager videoStreamManager;
+ //private AudioStreamManager audioStreamManager;
+
+
+ // Initialize proxyBridge with anonymous lifecycleListener
+ //FIXME changed from proxy bridge
+ 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){
+ initialize();
+ initStarted = true;
+ }
+ }
+ }
+
+ @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 onServiceEnded(LifecycleManager lifeCycleManager, OnServiceEnded serviceEnded) {
+
+ }
+
+ @Override
+ public void onServiceNACKed(LifecycleManager lifeCycleManager, OnServiceNACKed serviceNACKed) {
+
+ }
+
+ @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();
+ }
+ };
+
+ void checkState() {
+ if (permissionManager != null && fileManager != null && screenManager != null ){//FIXME && (!lockScreenConfig.isEnabled() || lockScreenManager != null)) {
+ if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY){ //FIXME && (!lockScreenConfig.isEnabled() || lockScreenManager.getState() == BaseSubManager.READY)) {
+ DebugTool.logInfo("Starting sdl manager, all sub managers are in ready state");
+ transitionToState(BaseSubManager.READY);
+ notifyDevListener(null);
+ onReady();
+ } else if (permissionManager.getState() == BaseSubManager.ERROR && fileManager.getState() == BaseSubManager.ERROR && screenManager.getState() == BaseSubManager.ERROR){ //FIXME && (!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){//FIXME || (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);
+ 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);
+ }
+ }
+ }
+
+ protected void initialize(){
+ // Instantiate sub managers
+ this.permissionManager = new PermissionManager(_internalInterface);
+ this.fileManager = new FileManager(_internalInterface); //FIXME ,context);
+ /* FIXME if (lockScreenConfig.isEnabled()) {
+ this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface);
+ }*/
+ this.screenManager = new ScreenManager(_internalInterface, this.fileManager);
+ /* FIXME 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);
+
+ }
+
+ /**
+ * Get the current state for the SdlManager
+ * @return int value that represents the current state
+ * @see BaseSubManager
+ */
+ public int getState() {
+ synchronized (STATE_LOCK) {
+ return state;
+ }
+ }
+
+ protected void transitionToState(int state) {
+ synchronized (STATE_LOCK) {
+ this.state = state;
+ }
+ }
+
+ //FIXME @SuppressLint("NewApi")
+ public void dispose() {
+ if (this.permissionManager != null) {
+ this.permissionManager.dispose();
+ }
+
+ if (this.fileManager != null) {
+ this.fileManager.dispose();
+ }
+
+ /*FIXME if (this.lockScreenManager != null) {
+ this.lockScreenManager.dispose();
+ }*/
+
+ if (this.screenManager != null) {
+ this.screenManager.dispose();
+ }
+
+ /* FIXME 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(managerListener != null){
+ managerListener.onDestroy(this);
+ managerListener = null;
+ }
+ }
+
+
+ private 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");
+ }
+ }
+
+ // MANAGER GETTERS
+
+ /**
+ * Gets the PermissionManager. <br>
+ * <strong>Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @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. <br>
+ * <strong>Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @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. <br>
+ * 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.
+ * <br><br><strong>Note: VideoStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @return a VideoStreamManager object attached to shit SdlManager instance
+ */
+ /* FIXME
+ public @Nullable
+ VideoStreamManager getVideoStreamManager() {
+ checkSdlManagerState();
+ return videoStreamManager;
+ }*/
+
+ /**
+ * Gets the AudioStreamManager. <br>
+ * 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.
+ * <br><strong>Note: AudioStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @return a AudioStreamManager object
+ */
+ /* FIXME public @Nullable AudioStreamManager getAudioStreamManager() {
+ checkSdlManagerState();
+ return audioStreamManager;
+ }*/
+
+ /**
+ * Gets the ScreenManager. <br>
+ * <strong>Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @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. <br>
+ * <strong>Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @return a LockScreenManager object
+ */
+ /* FIXME 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;
+ }*/
+
+ /**
+ * Gets the SystemCapabilityManager. <br>
+ * <strong>Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong>
+ * @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.
+ */
+ public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){
+ if(proxy != null){
+ return proxy.getRegisterAppInterfaceResponse();
+ }
+ return null;
+ }
+
+ /**
+ * Get the current OnHMIStatus
+ * @return OnHMIStatus object represents the current OnHMIStatus
+ */
+ public OnHMIStatus getCurrentHMIStatus(){
+ if(this.proxy !=null ){
+ return proxy.getCurrentHMIStatus();
+ }
+ return null;
+ }
+
+ /* *******************************************************************************************************
+ ************************************* FileStream Methods - START ****************************************
+ *********************************************************************************************************/
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ */
+ public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length) {
+ if (proxy != null){
+ proxy.putFileStream(inputStream, fileName, offset, length);
+ }
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ */
+ public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) {
+ if (proxy != null){
+ proxy.putFileStream(inputStream, fileName, offset, length, fileType, isPersistentFile, isSystemFile, cb);
+ }
+ }
+
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ */
+ public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length) {
+ if (proxy != null){
+ return proxy.putFileStream(fileName, offset, length);
+ }
+ return null;
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ */
+ public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) {
+ if (proxy != null){
+ return proxy.putFileStream(fileName, offset, length, fileType, isPersistentFile, isSystemFile, cb);
+ }
+ return null;
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param path The physical file path on the mobile device.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ * @param correlationId A unique id that correlates each RPCRequest and
+ * RPCResponse.
+ * @return RPCStreamController If the putFileStream was not started
+ * successfully null is returned, otherwise a valid object reference is
+ * returned .
+ */
+ public RPCStreamController putFileStream(String path, @NonNull String fileName, Long offset, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId, OnPutFileUpdateListener cb) {
+ if (proxy != null){
+ return proxy.putFileStream(path, fileName, offset, fileType, isPersistentFile, isSystemFile, isPayloadProtected, correlationId, cb);
+ }
+ return null;
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ * @param correlationId A unique id that correlates each RPCRequest and
+ * RPCResponse.
+ */
+ public RPCStreamController putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId) {
+ if (proxy != null){
+ return proxy.putFileStream(inputStream, fileName, offset, length, fileType, isPersistentFile, isSystemFile, isPayloadProtected, correlationId);
+ }
+ return null;
+
+ }
+
+ /**
+ * Used to end an existing putFileStream that was previously initiated with any putFileStream method.
+ */
+ public void endPutFileStream() {
+ if (proxy != null){
+ proxy.endPutFileStream();
+ }
+ }
+
+ public void endRPCStream() {
+ if (proxy != null){
+ proxy.endRPCStream();
+ }
+ }
+
+ public boolean startRPCStream(InputStream is, RPCRequest msg) {
+ if (proxy != null){
+ return proxy.startRPCStream(is, msg);
+ }
+ return false;
+ }
+
+ public OutputStream startRPCStream(RPCRequest msg) {
+ if (proxy != null){
+ return proxy.startRPCStream(msg);
+ }
+ return null;
+ }
+
+ /* *******************************************************************************************************
+ ************************************** FileStream Methods - END *****************************************
+ *********************************************************************************************************/
+
+
+ // PROTECTED GETTERS
+ protected String getAppName() { return appName; }
+
+ protected String getAppId() { return appId; }
+
+ protected String getShortAppName() { return shortAppName; }
+
+ protected Language getHmiLanguage() { return hmiLanguage; }
+
+ protected TemplateColorScheme getDayColorScheme() { return dayColorScheme; }
+
+ protected TemplateColorScheme getNightColorScheme() { return nightColorScheme; }
+
+ protected Vector<AppHMIType> getAppTypes() { return hmiTypes; }
+
+ protected Vector<String> getVrSynonyms() { return vrSynonyms; }
+
+ protected Vector<TTSChunk> getTtsChunks() { return ttsChunks; }
+
+ protected BaseTransportConfig getTransport() { return transport; }
+
+ //FIXME protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; }
+
+ // SENDING REQUESTS
+
+ /**
+ * Send RPC Message <br>
+ * <strong>Note: Only takes type of RPCRequest for now, notifications and responses will be thrown out</strong>
+ * @param message RPCMessage
+ */
+ public void sendRPC(RPCMessage message) {
+
+ if (message instanceof RPCRequest){
+ proxy.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 <br>
+ *
+ * <strong>NOTE: This will override any listeners on individual RPCs</strong><br>
+ *
+ * <strong>ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out</strong>
+ *
+ * @param rpcs is the list of RPCMessages being sent
+ * @param listener listener for updates and completions
+ */
+ public void sendSequentialRPCs(final List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener){
+
+ List<RPCRequest> 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) {
+ proxy.sendRpcsSequentially(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 <br>
+ *
+ * <strong>NOTE: This will override any listeners on individual RPCs</strong> <br>
+ *
+ * <strong>ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out</strong>
+ *
+ * @param rpcs is the list of RPCMessages being sent
+ * @param listener listener for updates and completions
+ */
+ public void sendRPCs(List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) {
+
+ List<RPCRequest> 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) {
+ proxy.sendRpcs(rpcRequestList, listener);
+ }
+ }
+
+ 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
+ */
+ public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
+ proxy.addOnRPCNotificationListener(notificationId,listener);
+ }
+
+ /**
+ * Remove an OnRPCNotificationListener
+ * @param listener listener that was previously added
+ */
+ public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
+ proxy.removeOnRPCNotificationListener(notificationId, listener);
+ }
+
+ // LIFECYCLE / OTHER
+
+ // STARTUP
+
+ /**
+ * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up
+ */
+ @SuppressWarnings("unchecked")
+ public void start(){
+ Log.i(TAG, "start");
+ if (proxy == null) {
+ //FIXME if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){
+ if (transport != null && transport.getTransportType().equals(TransportType.WEB_SOCKET_SERVER)) {
+ //Do the thing
+
+ /*FIXME MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport);
+ final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener();
+ multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() {
+ @Override
+ public void onTransportEvent(List<TransportRecord> 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);
+ }
+ }
+ });
+ }*/
+
+ LifecycleManager.AppConfig appConfig = new LifecycleManager.AppConfig();
+ appConfig.appName = appName;
+ //short app name
+ appConfig.isMediaApp = isMediaApp;
+ appConfig.hmiDisplayLanguageDesired = hmiLanguage;
+ appConfig.languageDesired = hmiLanguage;
+ appConfig.appType = hmiTypes;
+ appConfig.vrSynonyms = vrSynonyms;
+ appConfig.ttsName = ttsChunks;
+ appConfig.dayColorScheme = dayColorScheme;
+ appConfig.nightColorScheme = nightColorScheme;
+ appConfig.appID = appId;
+
+
+ proxy = new LifecycleManager(appConfig, (WebSocketServerConfig)transport, lifecycleListener);
+ proxy.start();
+ if (sdlSecList != null && !sdlSecList.isEmpty()) {
+ proxy.setSdlSecurityClassList(sdlSecList);
+ }
+
+ }else{
+ throw new RuntimeException("No transport provided");
+ }
+ }
+ }
+
+ /* FIXME protected void setProxy(SdlProxyBase proxy){
+ this.proxy = proxy;
+ }*/
+
+ // INTERNAL INTERFACE
+ private ISdl _internalInterface = new ISdl() {
+ @Override
+ public void start() {
+ proxy.start();
+ }
+
+ @Override
+ public void stop() {
+ proxy.stop();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return proxy.isConnected();
+ }
+
+ @Override
+ public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
+ //FIXME proxy.addServiceListener(serviceType,sdlServiceListener);
+ }
+
+ @Override
+ public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
+ //FIXME proxy.removeServiceListener(serviceType,sdlServiceListener);
+ }
+
+ @Override
+ public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) {
+ if(proxy.isConnected()){
+ //FIXME proxy.startVideoStream(encrypted,parameters);
+ }
+ }
+
+ @Override
+ public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){
+ return null; //FIXME proxy.startVideoStream(isEncrypted, parameters);
+ }
+
+ @Override
+ public void stopVideoService() {
+ if(proxy.isConnected()){
+ //FIXME proxy.endVideoStream();
+ }
+ }
+
+ @Override
+ public void startAudioService(boolean isEncrypted, AudioStreamingCodec codec,
+ AudioStreamingParams params) {
+ if(proxy.isConnected()){
+ //FIXME proxy.startAudioStream(isEncrypted, codec, params);
+ }
+ }
+
+ @Override
+ public void startAudioService(boolean encrypted) {
+ if(proxy.isConnected()){
+ //FIXME proxy.startService(SessionType.PCM, encrypted);
+ }
+ }
+
+ @Override
+ public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec,
+ AudioStreamingParams params) {
+ return null; //FIXME proxy.startAudioStream(isEncrypted, codec, params);
+ }
+
+ @Override
+ public void stopAudioService() {
+ if(proxy.isConnected()){
+ //FIXME proxy.endAudioStream();
+ }
+ }
+
+ @Override
+ public void sendRPCRequest(RPCRequest message){
+ if(message != null){
+ proxy.sendRpc(message);
+ }
+ }
+
+ @Override
+ public void sendRequests(List<? extends RPCRequest> rpcs, OnMultipleRequestListener listener) {
+ proxy.sendRpcs(rpcs, listener);
+ }
+
+ @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 addOnRPCListener(final FunctionID responseId, final OnRPCListener listener) {
+ proxy.addRpcListener(responseId, listener);
+ }
+
+ @Override
+ public boolean removeOnRPCListener(final FunctionID responseId, final OnRPCListener listener) {
+ return proxy.removeOnRPCListener(responseId, listener);
+ }
+
+ @Override
+ public Object getCapability(SystemCapabilityType systemCapabilityType){
+ return proxy.getSystemCapabilityManager().getCapability(systemCapabilityType);
+ }
+
+ @Override
+ public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) {
+ proxy.getSystemCapabilityManager().getCapability(systemCapabilityType, scListener);
+ }
+
+ @Override
+ public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){
+ return proxy.getSystemCapabilityManager().isCapabilitySupported(systemCapabilityType);
+ }
+
+ @Override
+ public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
+ proxy.getSystemCapabilityManager().addOnSystemCapabilityListener(systemCapabilityType, listener);
+ }
+
+ @Override
+ public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
+ return proxy.getSystemCapabilityManager().removeOnSystemCapabilityListener(systemCapabilityType, listener);
+ }
+
+ @Override
+ public boolean isTransportForServiceAvailable(SessionType serviceType) {
+ /* FIXME if(SessionType.NAV.equals(serviceType)){
+ return proxy.isVideoStreamTransportAvailable();
+ }else if(SessionType.PCM.equals(serviceType)){
+ return proxy.isAudioStreamTransportAvailable();
+ } */
+ return false;
+ }
+
+ @Override
+ public SdlMsgVersion getSdlMsgVersion(){
+ //FIXME this should be a breaking change to support our version
+ Version rpcSepcVersion = proxy.getRpcSepcVersion();
+ if(rpcSepcVersion != null){
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion();
+ sdlMsgVersion.setMajorVersion(rpcSepcVersion.getMajor());
+ sdlMsgVersion.setMinorVersion(rpcSepcVersion.getMinor());
+ sdlMsgVersion.setPatchVersion(rpcSepcVersion.getPatch());
+ return sdlMsgVersion;
+ }
+
+ return null;
+ }
+
+ @Override
+ public @NonNull Version getProtocolVersion() {
+ if(proxy.getProtocolVersion() != null){
+ return proxy.getProtocolVersion();
+ }else{
+ return new Version(1,0,0);
+ }
+ }
+
+ };
+
+
+ // 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
+ */
+ //FIXME public Builder(@NonNull Context context, @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){
+ sdlManager = new SdlManager();
+ //FIXME setContext(context);
+ setAppId(appId);
+ setAppName(appName);
+ 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 Language of the App
+ * @param hmiLanguage
+ */
+ public Builder setLanguage(final Language hmiLanguage){
+ sdlManager.hmiLanguage = hmiLanguage;
+ return this;
+ }
+
+ /**
+ * Sets the TemplateColorScheme for daytime
+ * @param dayColorScheme
+ */
+ public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){
+ sdlManager.dayColorScheme = dayColorScheme;
+ return this;
+ }
+
+ /**
+ * Sets the TemplateColorScheme for nighttime
+ * @param nightColorScheme
+ */
+ public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){
+ sdlManager.nightColorScheme = nightColorScheme;
+ return this;
+ }
+
+ /**
+ * Sets the LockScreenConfig for the session. <br>
+ * <strong>Note: If not set, the default configuration will be used.</strong>
+ * @param lockScreenConfig - configuration options
+ */
+ /*FIXME public Builder setLockScreenConfig (final LockScreenConfig lockScreenConfig){
+ sdlManager.lockScreenConfig = lockScreenConfig;
+ return this;
+ }*/
+
+ /**
+ * Sets the icon for the app on HU <br>
+ * @param sdlArtwork
+ */
+ public Builder setAppIcon(final SdlArtwork sdlArtwork){
+ sdlManager.appIcon = sdlArtwork;
+ return this;
+ }
+
+ /**
+ * Sets the vector of AppHMIType <br>
+ * <strong>Note: This should be an ordered list from most -> least relevant</strong>
+ * @param hmiTypes
+ */
+ public Builder setAppTypes(final Vector<AppHMIType> hmiTypes){
+
+ sdlManager.hmiTypes = hmiTypes;
+
+ if (hmiTypes != null) {
+ sdlManager.isMediaApp = hmiTypes.contains(AppHMIType.MEDIA);
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the vector of vrSynonyms
+ * @param vrSynonyms
+ */
+ public Builder setVrSynonyms(final Vector<String> vrSynonyms) {
+ sdlManager.vrSynonyms = vrSynonyms;
+ return this;
+ }
+
+ /**
+ * Sets the TTS Name
+ * @param ttsChunks
+ */
+ public Builder setTtsName(final Vector<TTSChunk> ttsChunks) {
+ sdlManager.ttsChunks = ttsChunks;
+ return this;
+ }
+
+ /**
+ * This Object type may change with the transport refactor
+ * Sets the BaseTransportConfig
+ * @param transport
+ */
+ public Builder setTransportType(BaseTransportConfig transport){
+ sdlManager.transport = transport;
+ return this;
+ }
+
+ /**
+ * Sets the Context
+ * @param context
+ */
+ /* FIXME public Builder setContext(Context context){
+ sdlManager.context = context;
+ return this;
+ }*/
+
+ /**
+ * Sets the Security library
+ * @param secList The list of security class(es)
+ */
+ public Builder setSdlSecurity(List<Class<? extends SdlSecurityBase>> secList) {
+ sdlManager.sdlSecList = secList;
+ return this;
+ }
+
+ /**
+ * Set the SdlManager Listener
+ * @param listener the listener
+ */
+ public Builder setManagerListener(@NonNull final SdlManagerListener listener){
+ sdlManager.managerListener = listener;
+ 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<AppHMIType> 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.hmiLanguage == null){
+ sdlManager.hmiLanguage = Language.EN_US;
+ }
+
+ sdlManager.transitionToState(BaseSubManager.SETTING_UP);
+
+ return sdlManager;
+ }
+ }
+
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java
new file mode 100644
index 000000000..f3c95045c
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java
@@ -0,0 +1,21 @@
+package com.smartdevicelink.managers;
+
+public interface SdlManagerListener extends BaseSdlManagerListener {
+
+ /**
+ * Called when a manager is ready for use
+ */
+ void onStart(SdlManager manager);
+
+ /**
+ * Called when the manager is destroyed
+ */
+ void onDestroy(SdlManager manager);
+
+ /**
+ * Called when the manager encounters an error
+ * @param info info regarding the error
+ * @param e the exception
+ */
+ void onError(SdlManager manager, String info, Exception e);
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/file/FileManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/file/FileManager.java
new file mode 100644
index 000000000..5c6317853
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/file/FileManager.java
@@ -0,0 +1,108 @@
+package com.smartdevicelink.managers.file;
+
+
+import android.support.annotation.NonNull;
+import com.smartdevicelink.managers.file.filetypes.SdlFile;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.PutFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * <strong>FileManager</strong> <br>
+ *
+ * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br>
+ *
+ * The SDLFileManager uploads files and keeps track of all the uploaded files names during a session. <br>
+ *
+ * We need to add the following struct: SDLFile<br>
+ *
+ * It is broken down to these areas: <br>
+ *
+ * 1. Getters <br>
+ * 2. Deletion methods <br>
+ * 3. Uploading Files / Artwork
+ */
+public class FileManager extends BaseFileManager {
+
+ public FileManager(ISdl internalInterface) {
+
+ // setup
+ super(internalInterface);
+ }
+
+ /**
+ * Creates and returns a PutFile request that would upload a given SdlFile
+ * @param file SdlFile with fileName and one of A) fileData, B) Uri, or C) resourceID set
+ * @return a valid PutFile request if SdlFile contained a fileName and sufficient data
+ */
+ @Override
+ PutFile createPutFile(@NonNull final SdlFile file){
+ PutFile putFile = new PutFile();
+ if(file.getName() == null){
+ throw new IllegalArgumentException("You must specify an file name in the SdlFile");
+ }else{
+ putFile.setSdlFileName(file.getName());
+ }
+
+ if(file.getFilePath() != null){
+ //Attempt to access the file via a path
+ byte[] data = contentsOfFilePath(file.getFilePath());
+ if(data != null ){
+ putFile.setFileData(data);
+ }else{
+ throw new IllegalArgumentException("File at path was empty");
+ }
+ }else if(file.getFileData() != null){
+ // Use file data (raw bytes) to upload file
+ putFile.setFileData(file.getFileData());
+ }else{
+ throw new IllegalArgumentException("The SdlFile to upload does " +
+ "not specify its resourceId, Uri, or file data");
+ }
+
+ if(file.getType() != null){
+ putFile.setFileType(file.getType());
+ }
+ putFile.setPersistentFile(file.isPersistent());
+
+ return putFile;
+ }
+
+ /**
+ *
+ * @param filePath
+ * @return
+ */
+ private byte[] contentsOfFilePath(String filePath){
+ File file = new File(filePath);
+ if(file.isFile() && file.canRead()){
+ FileInputStream fileInputStream = null;
+ byte[] bytesArray = null;
+
+ try {
+ bytesArray = new byte[(int) file.length()];
+
+ //read file into bytes[]
+ fileInputStream = new FileInputStream(file);
+ fileInputStream.read(bytesArray);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (fileInputStream != null) {
+ try {
+ fileInputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ return bytesArray;
+ }
+ return null;
+ }
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java b/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
new file mode 100644
index 000000000..aa2671689
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
@@ -0,0 +1,83 @@
+package com.smartdevicelink.managers.file.filetypes;
+
+import android.support.annotation.NonNull;
+
+import com.smartdevicelink.proxy.rpc.Image;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.ImageType;
+import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
+
+/**
+ * A class that extends SdlFile, representing artwork (JPEG, PNG, or BMP) to be uploaded to core
+ */
+public class SdlArtwork extends SdlFile {
+ private boolean isTemplate;
+ private Image imageRPC;
+
+ public SdlArtwork(){}
+
+ public SdlArtwork(@NonNull StaticIconName staticIconName) {
+ super(staticIconName);
+ }
+
+ public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, int id, boolean persistentFile) {
+ super(fileName, fileType, id, persistentFile);
+ }
+
+ /* FIXME public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, Uri uri, boolean persistentFile) {
+ super(fileName, fileType, uri, persistentFile);
+ }*/
+
+
+ public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, String filePath, boolean persistentFile) {
+ super(fileName, fileType, filePath, persistentFile);
+ }
+
+ public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, byte[] data, boolean persistentFile) {
+ super(fileName, fileType, data, persistentFile);
+ }
+
+ /**
+ * Set whether this SdlArtwork is a template image whose coloring should be decided by the HMI
+ * @param isTemplate boolean that tells whether this SdlArtwork is a template image
+ */
+ public void setTemplateImage(boolean isTemplate){
+ this.isTemplate = isTemplate;
+ }
+
+ /**
+ * Get whether this SdlArtwork is a template image whose coloring should be decided by the HMI
+ * @return boolean that tells whether this SdlArtwork is a template image
+ */
+ public boolean isTemplateImage(){
+ return isTemplate;
+ }
+
+
+ @Override
+ public void setType(@NonNull FileType fileType) {
+ if(fileType.equals(FileType.GRAPHIC_JPEG) || fileType.equals(FileType.GRAPHIC_PNG)
+ || fileType.equals(FileType.GRAPHIC_BMP)){
+ super.setType(fileType);
+ }else{
+ throw new IllegalArgumentException("Only JPEG, PNG, and BMP image types are supported.");
+ }
+ }
+
+ /**
+ * Get the Image RPC representing this artwork. Generally for use internally, you should instead pass an artwork to a Screen Manager method.
+ * @return The Image RPC representing this artwork.
+ */
+ public Image getImageRPC() {
+ if (imageRPC == null) {
+ if (isStaticIcon()) {
+ imageRPC = new Image(getName(), ImageType.STATIC);
+ imageRPC.setIsTemplate(true);
+ } else {
+ imageRPC = new Image(getName(), ImageType.DYNAMIC);
+ imageRPC.setIsTemplate(isTemplate);
+ }
+ }
+ return imageRPC;
+ }
+} \ No newline at end of file
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java b/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java
new file mode 100644
index 000000000..789515c48
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java
@@ -0,0 +1,114 @@
+package com.smartdevicelink.managers.file.filetypes;
+
+import android.support.annotation.NonNull;
+
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
+
+/**
+ * A class representing data to be uploaded to core
+ */
+public class SdlFile{
+ private String fileName;
+ private int id = -1;
+ //FIXME private Uri uri;
+ private String filePath;
+ private byte[] fileData;
+ private FileType fileType;
+ private boolean persistentFile;
+ private boolean isStaticIcon;
+
+ public SdlFile(){}
+
+ public SdlFile(@NonNull StaticIconName staticIconName){
+ this.fileName = staticIconName.toString();
+ this.fileData = staticIconName.toString().getBytes();
+ this.persistentFile = false;
+ this.isStaticIcon = true;
+ }
+
+ public SdlFile(@NonNull String fileName, @NonNull FileType fileType, int id, boolean persistentFile){
+ this.fileName = fileName;
+ this.fileType = fileType;
+ this.id = id;
+ this.persistentFile = persistentFile;
+ }
+
+ /*public SdlFile(@NonNull String fileName, @NonNull FileType fileType, Uri uri, boolean persistentFile){
+ this.fileName = fileName;
+ this.fileType = fileType;
+ this.uri = uri;
+ this.persistentFile = persistentFile;
+ }*/
+
+ public SdlFile(@NonNull String fileName, @NonNull FileType fileType, byte[] data, boolean persistentFile){
+ this.fileName = fileName;
+ this.fileType = fileType;
+ this.fileData = data;
+ this.persistentFile = persistentFile;
+ }
+
+ public SdlFile(@NonNull String fileName, @NonNull FileType fileType, String filePath, boolean persistentFile){
+ this.fileName = fileName;
+ this.fileType = fileType;
+ this.filePath = filePath;
+ this.persistentFile = persistentFile;
+ }
+
+ public void setName(@NonNull String fileName){
+ this.fileName = fileName;
+ }
+ public String getName(){
+ return fileName;
+ }
+
+ public void setResourceId(int id){
+ this.id = id;
+ }
+ public int getResourceId(){
+ return id;
+ }
+
+ /* FIXME public void setUri(Uri uri){
+ this.uri = uri;
+ }
+ public Uri getUri(){
+ return uri;
+ }*/
+
+ public void setFilePath(String filePath){
+ this.filePath = filePath;
+ }
+
+ public String getFilePath(){
+ return this.filePath;
+ }
+
+ public void setFileData(byte[] data){
+ this.fileData = data;
+ }
+ public byte[] getFileData(){
+ return fileData;
+ }
+
+ public void setType(@NonNull FileType fileType){
+ this.fileType = fileType;
+ }
+ public FileType getType(){
+ return fileType;
+ }
+
+ public void setPersistent(boolean persistentFile){
+ this.persistentFile = persistentFile;
+ }
+ public boolean isPersistent(){
+ return this.persistentFile;
+ }
+
+ public void setStaticIcon(boolean staticIcon) {
+ isStaticIcon = staticIcon;
+ }
+ public boolean isStaticIcon() {
+ return isStaticIcon;
+ }
+} \ No newline at end of file
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java
new file mode 100644
index 000000000..81933e588
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java
@@ -0,0 +1,1182 @@
+package com.smartdevicelink.managers.lifecycle;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+import com.smartdevicelink.SdlConnection.SdlSession;
+import com.smartdevicelink.exception.SdlException;
+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.*;
+import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
+import com.smartdevicelink.proxy.callbacks.OnServiceNACKed;
+import com.smartdevicelink.proxy.interfaces.*;
+import com.smartdevicelink.proxy.rpc.*;
+import com.smartdevicelink.proxy.rpc.enums.*;
+import com.smartdevicelink.proxy.rpc.listeners.*;
+import com.smartdevicelink.security.SdlSecurityBase;
+import com.smartdevicelink.streaming.StreamRPCPacketizer;
+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.WebSocketServerConfig;
+import com.smartdevicelink.util.CorrelationIdGenerator;
+import com.smartdevicelink.util.DebugTool;
+import com.smartdevicelink.util.Version;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class LifecycleManager extends BaseLifecycleManager {
+
+ private static final String TAG = "Lifecycle Manager";
+
+ public static final Version MAX_SUPPORTED_RPC_VERSION = new Version("5.0.0");
+
+ // Protected Correlation IDs
+ private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529;
+
+
+ // Sdl Synchronization Objects
+ private static final Object RPC_LISTENER_LOCK = new Object(),
+ ON_UPDATE_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;
+
+ //FIXME these were sparse arrays in android
+ protected final HashMap<Integer,CopyOnWriteArrayList<OnRPCListener>> rpcListeners;
+ protected final HashMap<Integer, OnRPCResponseListener> rpcResponseListeners;
+ protected final HashMap<Integer, CopyOnWriteArrayList<OnRPCNotificationListener>> rpcNotificationListeners;
+
+ protected final SystemCapabilityManager systemCapabilityManager;
+
+ protected RegisterAppInterfaceResponse raiResponse = null;
+
+ private OnHMIStatus currentHMIStatus;
+ protected boolean firstTimeFull = true;
+
+ final LifecycleListener lifecycleListener;
+
+ private List<Class<? extends SdlSecurityBase>> _secList = null;
+
+
+ public LifecycleManager(AppConfig appConfig, WebSocketServerConfig config, LifecycleListener listener){
+
+ this.lifecycleListener = listener;
+
+ this.rpcListeners = new HashMap<>();
+ this.rpcResponseListeners = new HashMap<>();
+ this.rpcNotificationListeners = new HashMap<>();
+
+ this.appConfig = appConfig;
+ this.session = new SdlSession(this, config);
+
+ this.systemCapabilityManager = new SystemCapabilityManager(internalInterface);
+
+
+ }
+
+ public void start(){
+ try {
+ setupInternalRpcListeners();
+ session.startSession();
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void stop(){
+ //TODO stop
+ }
+
+ public Version getProtocolVersion(){
+ if (session != null){
+ return session.getProtocolVersion();
+ }
+ return new Version(1,0,0);
+ }
+ public Version getRpcSepcVersion(){
+ return rpcSpecVersion;
+ }
+
+ public void sendRpc(RPCMessage message){
+ this.sendRPCMessagePrivate(message);
+ }
+
+ public void sendRpcs(List<? extends RPCMessage> messages, OnMultipleRequestListener listener){
+ if(messages != null ){
+ for(RPCMessage message : messages){
+ if(message instanceof RPCRequest){
+ RPCRequest request = ((RPCRequest) message);
+ request.setCorrelationID(CorrelationIdGenerator.generateId());
+ if(listener != null){
+ listener.addCorrelationId(request.getCorrelationID());
+ request.setOnRPCResponseListener(listener.getSingleRpcResponseListener());
+ }
+ this.sendRPCMessagePrivate(request);
+
+ }else{
+ this.sendRPCMessagePrivate(message);
+ }
+ }
+ }
+ }
+
+ //Sequentially
+ public void sendRpcsSequentially(List<? extends RPCMessage> messages, OnMultipleRequestListener listener){
+ //FIXME yea
+ sendRpcs(messages, listener);
+ }
+
+ public SystemCapabilityManager getSystemCapabilityManager(){
+ return systemCapabilityManager;
+ }
+
+ public 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);
+ }
+ }
+
+
+ /* *******************************************************************************************************
+ ********************************** 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;
+ }
+ 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:
+ 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();
+ }
+ break;
+ case ON_APP_INTERFACE_UNREGISTERED:
+ Log.v(TAG, "on app interface unregistered");
+ cleanProxy();
+ break;
+ case UNREGISTER_APP_INTERFACE:
+ Log.v(TAG, "unregister app interface");
+ cleanProxy();
+ break;
+ }
+ }
+ }
+
+
+
+ };
+
+ /* *******************************************************************************************************
+ ********************************** INTERNAL - RPC LISTENERS !! END !! *********************************
+ *********************************************************************************************************/
+
+
+ /* *******************************************************************************************************
+ ********************************** METHODS - RPC LISTENERS !! START !! **********************************
+ *********************************************************************************************************/
+
+ public boolean onRPCReceived(final RPCMessage message){
+ synchronized(RPC_LISTENER_LOCK){
+ if(message == null || message.getFunctionID() == null){
+ return false;
+ }
+
+ final int id = message.getFunctionID().getId();
+ CopyOnWriteArrayList<OnRPCListener> listeners = rpcListeners.get(id);
+ if(listeners!=null && listeners.size()>0) {
+ for (OnRPCListener listener : listeners) {
+ listener.onReceived(message);
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+ //FIXME check if we need this to be public
+ public 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<OnRPCListener>());
+ }
+
+ rpcListeners.get(id.getId()).add(listener);
+ }
+ }
+ }
+
+ public 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")
+ public 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,
+ * <p>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.
+ */
+ public 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")
+ public HashMap<Integer, OnRPCResponseListener> getResponseListeners(){
+ synchronized(ON_UPDATE_LISTENER_LOCK){
+ return this.rpcResponseListeners;
+ }
+ }
+
+ @SuppressWarnings("UnusedReturnValue")
+ public 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<OnRPCNotificationListener> 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 ad 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")
+ public 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<OnRPCNotificationListener>());
+ }
+ rpcNotificationListeners.get(notificationId.getId()).add(listener);
+ }
+ }
+ }
+
+ /**
+ * This method is no longer valid and will not remove the listener for the supplied notificaiton id
+ * @param notificationId n/a
+ * @see #removeOnRPCNotificationListener(FunctionID, OnRPCNotificationListener)
+ */
+ @SuppressWarnings("unused")
+ @Deprecated
+ public void removeOnRPCNotificationListener(FunctionID notificationId){
+ synchronized(ON_NOTIFICATION_LISTENER_LOCK){
+ //rpcNotificationListeners.delete(notificationId.getId());
+ }
+ }
+
+ public 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;
+ }
+
+
+
+ /* *******************************************************************************************************
+ **************************************** RPC LISTENERS !! END !! ****************************************
+ *********************************************************************************************************/
+
+
+
+ //FIXME move to SdlSession
+ private void sendRPCMessagePrivate(RPCMessage message){
+ try {
+
+ message.format(rpcSpecVersion,true);
+ byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor());
+
+ 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()));
+ pm.setPayloadProtected(message.isPayloadProtected());
+ if(RPCMessage.KEY_REQUEST.equals(message.getMessageType())){
+ Integer corrId = ((RPCRequest)message).getCorrelationID();
+ if( corrId== null) {
+
+ //FIXME Log error here
+ //throw new SdlException("CorrelationID cannot be null. RPC: " + message.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT);
+ Log.e(TAG, "No correlation ID attatched to request. Not sending");
+ }else{
+ pm.setCorrID(corrId);
+
+ OnRPCResponseListener listener = ((RPCRequest)message).getOnRPCResponseListener();
+ if(listener != null){
+ addOnRPCResponseListener(listener, corrId, msgBytes.length);
+ }
+ }
+ }
+
+ 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 ************************************
+ *********************************************************************************************************/
+
+
+ @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);
+
+ FunctionID functionID = rpc.getFunctionID();
+ if (functionID != null && (functionID.equals(FunctionID.ON_BUTTON_PRESS.toString()) || functionID.equals(FunctionID.ON_BUTTON_EVENT.toString())) ) {
+ rpc = handleButtonNotificationFormatting(rpc);
+ }
+
+ onRPCReceived(rpc);
+
+ if(RPCMessage.KEY_RESPONSE.equals(messageType)){
+
+ onRPCResponseReceived((RPCResponse)rpc);
+
+ }else if(RPCMessage.KEY_NOTIFICATION.equals(messageType)){
+
+ onRPCNotificationReceived((RPCNotification)rpc);
+ }
+ }else{
+ Log.w(TAG, "Shouldn't be here");
+ }
+ }
+
+ }
+
+ @Override
+ public void onProtocolSessionStartedNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID, List<String> 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 (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.appName,appConfig.isMediaApp, appConfig.languageDesired,
+ appConfig.hmiDisplayLanguageDesired,appConfig.appID);
+ rai.setCorrelationID(REGISTER_APP_INTERFACE_CORRELATION_ID);
+
+ rai.setTtsName(appConfig.ttsName);
+ rai.setNgnMediaScreenAppName(appConfig.ngnMediaScreenAppName);
+ rai.setVrSynonyms(appConfig.vrSynonyms);
+ rai.setAppHMIType(appConfig.appType);
+ rai.setDayColorScheme(appConfig.dayColorScheme);
+ rai.setNightColorScheme(appConfig.nightColorScheme);
+
+ //TODO Previous versions have set device info
+ //TODO attach previous hash id
+
+ sendRPCMessagePrivate(rai);
+ }else{
+ Log.e(TAG, "App config was null, soo...");
+ }
+
+
+ } else if (sessionType.eq(SessionType.NAV)) {
+ //FIXME NavServiceStarted();
+ } else if (sessionType.eq(SessionType.PCM)) {
+ //FIXME AudioServiceStarted();
+ }
+
+ }
+ }
+
+ @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) {
+ //FIXME
+ }
+
+ @Override
+ public void onHeartbeatTimedOut(byte sessionID) {
+ //FIXME
+ }
+
+ @Override
+ public void onProtocolServiceDataACK(SessionType sessionType, int dataSize, byte sessionID) {
+
+ }
+
+ /* *******************************************************************************************************
+ *************************************** 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) {
+
+ }
+
+ @Override
+ public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
+
+ }
+
+ @Override
+ public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) {
+
+ }
+
+ @Override
+ public void stopVideoService() {
+
+ }
+
+ @Override
+ public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
+ return null;
+ }
+
+ @Override
+ public void startAudioService(boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params) {
+
+ }
+
+ @Override
+ public void startAudioService(boolean encrypted) {
+
+ }
+
+ @Override
+ public void stopAudioService() {
+
+ }
+
+ @Override
+ public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, AudioStreamingParams params) {
+ return null;
+ }
+
+ @Override
+ public void sendRPCRequest(RPCRequest message) {
+ LifecycleManager.this.sendRPCMessagePrivate(message);
+
+ }
+
+ @Override
+ public void sendRequests(List<? extends RPCRequest> rpcs, OnMultipleRequestListener listener) {
+ //FIXME
+ }
+
+ @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 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) {
+ return LifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType);
+ }
+
+ @Override
+ public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) {
+ LifecycleManager.this.systemCapabilityManager.getCapability(systemCapabilityType,scListener);
+
+ }
+
+ @Override
+ public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType) {
+ return LifecycleManager.this.systemCapabilityManager.isCapabilitySupported(systemCapabilityType);
+ }
+
+ @Override
+ public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
+ LifecycleManager.this.systemCapabilityManager.addOnSystemCapabilityListener(systemCapabilityType,listener);
+
+ }
+
+ @Override
+ public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
+ return LifecycleManager.this.systemCapabilityManager.removeOnSystemCapabilityListener(systemCapabilityType,listener);
+ }
+
+ @Override
+ public boolean isTransportForServiceAvailable(SessionType serviceType) {
+ return LifecycleManager.this.session.isTransportForServiceAvailable(serviceType);
+ }
+
+ @Override
+ public SdlMsgVersion getSdlMsgVersion() {
+ return null; //FIXME should probably be rpc spec version
+ }
+
+ @Override
+ public Version getProtocolVersion() {
+ return LifecycleManager.this.getProtocolVersion();
+ }
+ };
+
+ /* *******************************************************************************************************
+ ********************************************* ISdl - END ************************************************
+ *********************************************************************************************************/
+
+ public interface LifecycleListener{
+ void onProxyConnected(LifecycleManager lifeCycleManager);
+ void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason);
+ void onServiceEnded(LifecycleManager lifeCycleManager, OnServiceEnded serviceEnded);
+ void onServiceNACKed(LifecycleManager lifeCycleManager, OnServiceNACKed serviceNACKed);
+ void onError(LifecycleManager lifeCycleManager, String info, Exception e);
+ }
+
+ public static class AppConfig{
+ //FIXME change these from public
+ public String appID, appName, ngnMediaScreenAppName;
+ public Vector<TTSChunk> ttsName;
+ public Vector<String> vrSynonyms;
+ public boolean isMediaApp = false;
+ public Language languageDesired, hmiDisplayLanguageDesired;
+ public Vector<AppHMIType> appType;
+ public TemplateColorScheme dayColorScheme, nightColorScheme;
+
+ private void prepare(){
+ if (ngnMediaScreenAppName == null) {
+ ngnMediaScreenAppName = appName;
+ }
+
+ if (languageDesired == null) {
+ languageDesired = Language.EN_US;
+ }
+
+ if (hmiDisplayLanguageDesired == null) {
+ hmiDisplayLanguageDesired = Language.EN_US;
+ }
+
+ if (vrSynonyms == null) {
+ vrSynonyms = new Vector<>();
+ vrSynonyms.add(appName);
+ }
+ }
+ }
+
+
+ //FIXME
+ /**
+ * 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
+ */
+ 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 (session != null && session.getIsConnected()) {
+ session.close();
+ }
+ }
+
+ public void setSdlSecurityClassList(List<Class<? extends SdlSecurityBase>> list) {
+ _secList = list;
+ }
+
+ 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<? extends SdlSecurityBase> cls : _secList) {
+ try {
+ sec = cls.newInstance();
+ } catch (Exception e) {
+ continue;
+ }
+
+ if ((sec != null) && (sec.getMakeList() != null)) {
+ if (sec.getMakeList().contains(make)) {
+ sec.setAppId(appConfig.appID);
+ if (session != null) {
+ session.setSdlSecurity(sec);
+ sec.handleSdlSession(session);
+ }
+ return;
+ }
+ }
+ }
+ }
+
+
+ /* *******************************************************************************************************
+ ************************************* FileStream Methods - START ****************************************
+ *********************************************************************************************************/
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ */
+ public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length) {
+ PutFile msg = new PutFile(fileName, FileType.BINARY);
+ msg.setCorrelationID(10000);
+ msg.setSystemFile(true);
+ msg.setOffset(offset);
+ msg.setLength(length);
+
+ startRPCStream(inputStream, msg);
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ */
+ public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) {
+ PutFile msg = new PutFile(fileName, FileType.BINARY);
+ msg.setCorrelationID(10000);
+ msg.setSystemFile(true);
+ msg.setOffset(offset);
+ msg.setLength(length);
+ msg.setOnPutFileUpdateListener(cb);
+ startRPCStream(inputStream, msg);
+ }
+
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ */
+ public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length) {
+ PutFile msg = new PutFile(fileName, FileType.BINARY);
+ msg.setCorrelationID(10000);
+ msg.setSystemFile(true);
+ msg.setOffset(offset);
+ msg.setLength(length);
+
+ return startRPCStream(msg);
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ */
+ public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) {
+ PutFile msg = new PutFile(fileName, FileType.BINARY);
+ msg.setCorrelationID(10000);
+ msg.setSystemFile(true);
+ msg.setOffset(offset);
+ msg.setLength(length);
+ msg.setOnPutFileUpdateListener(cb);
+
+ return startRPCStream(msg);
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param path The physical file path on the mobile device.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ * @param correlationId A unique id that correlates each RPCRequest and
+ * RPCResponse.
+ * @return RPCStreamController If the putFileStream was not started
+ * successfully null is returned, otherwise a valid object reference is
+ * returned .
+ */
+ public RPCStreamController putFileStream(String path, @NonNull String fileName, Long offset, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId, OnPutFileUpdateListener cb) {
+ PutFile msg = new PutFile(fileName, fileType);
+ msg.setCorrelationID(correlationId);
+ msg.setPersistentFile(isPersistentFile);
+ msg.setSystemFile(isSystemFile);
+ msg.setOffset(offset);
+ msg.setLength(0L);
+ msg.setPayloadProtected(isPayloadProtected);
+ msg.setOnPutFileUpdateListener(cb);
+
+ if (session == null) return null;
+
+ FileInputStream is = null;
+ try {
+ is = new FileInputStream(path);
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+
+
+ if (is == null) return null;
+
+ Long lSize = null;
+
+ try {
+ lSize = is.getChannel().size();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (lSize == null) {
+ try {
+ is.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ try {
+ StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer(this, session, is, msg, SessionType.RPC, session.getSessionId(), getProtocolVersion(), rpcSpecVersion, lSize, session);
+ rpcPacketizer.start();
+ return new RPCStreamController(rpcPacketizer, msg.getCorrelationID());
+ } catch (Exception e) {
+ Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * Used to push a binary stream of file data onto the module from a mobile device.
+ *
+ * @param inputStream The input stream of byte data that will be read from.
+ * @param fileName The SDL file reference name used by the RPC.
+ * @param offset The data offset in bytes. A value of zero is used to
+ * indicate data starting from the beginning of the file and a value greater
+ * than zero is used for resuming partial data chunks.
+ * @param length The total length of the file being sent.
+ * @param fileType The selected file type. See the {@link FileType} enum for
+ * details.
+ * @param isPersistentFile Indicates if the file is meant to persist between
+ * sessions / ignition cycles.
+ * @param isSystemFile Indicates if the file is meant to be passed through
+ * core to elsewhere in the system.
+ * @param correlationId A unique id that correlates each RPCRequest and
+ * RPCResponse.
+ */
+ public RPCStreamController putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId) {
+ PutFile msg = new PutFile(fileName, fileType);
+ msg.setCorrelationID(correlationId);
+ msg.setPersistentFile(isPersistentFile);
+ msg.setSystemFile(isSystemFile);
+ msg.setOffset(offset);
+ msg.setLength(length);
+ msg.setPayloadProtected(isPayloadProtected);
+
+ if (session == null) return null;
+ Long lSize = msg.getLength();
+
+ if (lSize == null) {
+ return null;
+ }
+
+ try {
+ StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer(this, session, inputStream, msg, SessionType.RPC, session.getSessionId(), getProtocolVersion(), rpcSpecVersion, lSize, session);
+ rpcPacketizer.start();
+ return new RPCStreamController(rpcPacketizer, msg.getCorrelationID());
+ } catch (Exception e) {
+ Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * Used to end an existing putFileStream that was previously initiated with any putFileStream method.
+ */
+ public void endPutFileStream() {
+ endRPCStream();
+ }
+
+ public void endRPCStream() {
+ if (this.session == null) return;
+ session.stopRPCStream();
+ }
+
+ public boolean startRPCStream(InputStream is, RPCRequest msg) {
+ if (session == null) return false;
+ session.startRPCStream(is, msg, SessionType.RPC, session.getSessionId(), (byte) getProtocolVersion().getMajor());
+ return true;
+ }
+
+ public OutputStream startRPCStream(RPCRequest msg) {
+ if (session == null) return null;
+ return session.startRPCStream(msg, SessionType.RPC, session.getSessionId(), (byte) getProtocolVersion().getMajor());
+ }
+
+ /* *******************************************************************************************************
+ ************************************** FileStream Methods - END *****************************************
+ *********************************************************************************************************/
+
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/permission/PermissionManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/permission/PermissionManager.java
new file mode 100644
index 000000000..127aaf0dc
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/permission/PermissionManager.java
@@ -0,0 +1,24 @@
+package com.smartdevicelink.managers.permission;
+
+import android.support.annotation.NonNull;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+
+/**
+ PermissionManager gives the developer information about what permissions are permitted in specific HMI level
+ and helps developers setup listeners to be called when specific permissions become allowed.<br>
+
+ This should be used through the {@link com.smartdevicelink.managers.SdlManager} and not be instantiated by itself
+**/
+
+ public class PermissionManager extends BasePermissionManager{
+
+
+ /**
+ * Creates a new instance of the PermissionManager
+ *
+ * @param internalInterface
+ */
+ public PermissionManager(@NonNull ISdl internalInterface) {
+ super(internalInterface);
+ }
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/screen/ScreenManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/screen/ScreenManager.java
new file mode 100644
index 000000000..42e838cd1
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/screen/ScreenManager.java
@@ -0,0 +1,18 @@
+package com.smartdevicelink.managers.screen;
+
+import android.support.annotation.NonNull;
+
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+
+/**
+ * <strong>ScreenManager</strong> <br>
+ *
+ * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br>
+*/
+public class ScreenManager extends BaseScreenManager {
+
+ public ScreenManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager) {
+ super(internalInterface, fileManager);
+ }
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/screen/SoftButtonManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/screen/SoftButtonManager.java
new file mode 100644
index 000000000..23cca49ea
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/screen/SoftButtonManager.java
@@ -0,0 +1,24 @@
+package com.smartdevicelink.managers.screen;
+
+import android.support.annotation.NonNull;
+
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+
+/**
+ * <strong>SoftButtonManager</strong> <br>
+ * SoftButtonManager gives the developer the ability to control how soft buttons are displayed on the head unit.<br>
+ * Note: This class must be accessed through the SdlManager->ScreenManager. Do not instantiate it by itself.<br>
+ */
+class SoftButtonManager extends BaseSoftButtonManager {
+
+ /**
+ * Creates a new instance of the SoftButtonManager
+ *
+ * @param internalInterface
+ * @param fileManager
+ */
+ SoftButtonManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager) {
+ super(internalInterface, fileManager);
+ }
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java
new file mode 100644
index 000000000..c7e9e0965
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java
@@ -0,0 +1,32 @@
+package com.smartdevicelink.managers.screen;
+
+import android.support.annotation.NonNull;
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+
+/**
+ * <strong>TextAndGraphicManager</strong> <br>
+ *
+ * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br>
+ *
+ */
+class TextAndGraphicManager extends BaseTextAndGraphicManager {
+
+ TextAndGraphicManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager, @NonNull SoftButtonManager softButtonManager) {
+ super(internalInterface, fileManager, softButtonManager);
+ }
+
+ @Override
+ SdlArtwork getBlankArtwork(){
+ if (blankArtwork == null){
+ blankArtwork = new SdlArtwork();
+ blankArtwork.setType(FileType.GRAPHIC_PNG);
+ blankArtwork.setName("blankArtwork");
+ blankArtwork.setFileData(new byte[50]);
+ //FIXME blankArtwork.setResourceId(R.drawable.transparent);
+ }
+ return blankArtwork;
+ }
+}
diff --git a/javaSE/src/main/java/com/smartdevicelink/security/SdlSecurityBase.java b/javaSE/src/main/java/com/smartdevicelink/security/SdlSecurityBase.java
new file mode 100644
index 000000000..3d5460aaa
--- /dev/null
+++ b/javaSE/src/main/java/com/smartdevicelink/security/SdlSecurityBase.java
@@ -0,0 +1,5 @@
+package com.smartdevicelink.security;
+
+public abstract class SdlSecurityBase extends BaseSdlSecurityBase{
+
+}
diff --git a/javaSE/src/main/java/hello_sdl/Main.java b/javaSE/src/main/java/hello_sdl/Main.java
new file mode 100644
index 000000000..0abcf803d
--- /dev/null
+++ b/javaSE/src/main/java/hello_sdl/Main.java
@@ -0,0 +1,186 @@
+package hello_sdl;
+
+import android.util.Log;
+import com.smartdevicelink.managers.SdlManager;
+import com.smartdevicelink.managers.SdlManagerListener;
+import com.smartdevicelink.managers.lifecycle.LifecycleManager;
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCNotification;
+import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
+import com.smartdevicelink.proxy.callbacks.OnServiceNACKed;
+import com.smartdevicelink.proxy.rpc.*;
+import com.smartdevicelink.proxy.rpc.enums.HMILevel;
+import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
+import com.smartdevicelink.transport.WebSocketServerConfig;
+import com.smartdevicelink.util.Version;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class Main {
+
+ private static final String TAG = "hello_sdl.Main";
+
+ public static void main(String[] args) {
+ // testRAIString();
+ startSdl();
+ }
+
+ public static void testRAI(){
+
+
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion();
+ sdlMsgVersion.setMajorVersion(5);
+ sdlMsgVersion.setMinorVersion(0);
+ sdlMsgVersion.setPatchVersion(0);
+
+ RegisterAppInterface rai = new RegisterAppInterface(sdlMsgVersion,
+ "AppName",false, null,
+ null,"78srtv78vt789vs29");
+
+ rai.setCorrelationID(65529);
+
+ rai.format(new Version(5,0,0),true);
+
+ byte[] msgBytes = JsonRPCMarshaller.marshall(rai, (byte)4);
+ }
+
+ public static void testRAIString(){
+
+ String rawRai = "{\r\n \"request\":{\r\n \"name\":\"RegisterAppInterface\",\r\n \"correlationID\":141,\r\n \"parameters\":{\r\n \"ttsName\":[\r\n {\r\n \"text\":\"Phrase 1\",\r\n \"type\":\"TEXT\"\r\n },\r\n {\r\n \"text\":\"Phrase 2\",\r\n \"type\":\"TEXT\"\r\n }\r\n ],\r\n \"hmiDisplayLanguageDesired\":\"EN-US\",\r\n \"appHMIType\":[\r\n \"SOCIAL\",\r\n \"MEDIA\"\r\n ],\r\n \"appID\":\"t4weGRSWY\",\r\n \"languageDesired\":\"PT-BR\",\r\n \"deviceInfo\":{\r\n \"hardware\":\"My Hardware\",\r\n \"firmwareRev\":\"My Firmware Revision\",\r\n \"os\":\"Windows\",\r\n \"osVersion\":\"95\",\r\n \"carrier\":\"nobody\",\r\n \"maxNumberRFCOMMPorts\":2\r\n },\r\n \"appName\":\"Dumb app\",\r\n \"ngnMediaScreenAppName\":\"DA\",\r\n \"isMediaApplication\":true,\r\n \"vrSynonyms\":[\r\n \"dumb\",\r\n \"really dumb app\"\r\n ],\r\n \"syncMsgVersion\":{\r\n \"majorVersion\":3,\r\n \"minorVersion\":64\r\n },\r\n \"hashID\":\"y534htz\"\r\n }\r\n },\r\n \"response\":{\r\n \"name\":\"RegisterAppInterfaceResponse\",\r\n \"correlationID\":142,\r\n \"parameters\":{\r\n \"vehicleType\":{\r\n \"make\":\"Chrysler\",\r\n \"model\":\"Crossfire\",\r\n \"modelYear\":\"1820\",\r\n \"trim\":\"Gold\"\r\n },\r\n \"speechCapabilities\":[\r\n \"SAPI_PHONEMES\",\r\n \"TEXT\",\r\n \"PRE_RECORDED\"\r\n ],\r\n \"vrCapabilities\":[\r\n \"Text\"\r\n ],\r\n \"audioPassThruCapabilities\":[\r\n {\r\n \"samplingRate\":\"16KHZ\",\r\n \"audioType\":\"PCM\",\r\n \"bitsPerSample\":\"16_BIT\"\r\n },\r\n {\r\n \"samplingRate\":\"44KHZ\",\r\n \"audioType\":\"PCM\",\r\n \"bitsPerSample\":\"8_BIT\"\r\n }\r\n ],\r\n \"hmiZoneCapabilities\":[\r\n \"FRONT\",\r\n \"BACK\"\r\n ],\r\n \"prerecordedSpeech\":[\r\n \"HELP_JINGLE\",\r\n \"LISTEN_JINGLE\",\r\n \"NEGATIVE_JINGLE\"\r\n ],\r\n \"supportedDiagModes\":[\r\n 324,\r\n 2356,\r\n 865,\r\n 211,\r\n 8098\r\n ],\r\n \"syncMsgVersion\":{\r\n \"majorVersion\":3,\r\n \"minorVersion\":64\r\n },\r\n \"language\":\"EN-US\",\r\n \"buttonCapabilities\":[\r\n {\r\n \"name\":\"SEEKRIGHT\",\r\n \"shortPressAvailable\":true,\r\n \"longPressAvailable\":false,\r\n \"upDownAvailable\":true\r\n },\r\n {\r\n \"name\":\"TUNEDOWN\",\r\n \"shortPressAvailable\":false,\r\n \"longPressAvailable\":true,\r\n \"upDownAvailable\":false\r\n }\r\n ],\r\n \"displayCapabilities\":{\r\n \"displayType\":\"TYPE2\",\r\n \"mediaClockFormats\":[\r\n \"CLOCKTEXT3\",\r\n \"CLOCK1\"\r\n ],\r\n \"textFields\":[\r\n {\r\n \"width\":480,\r\n \"characterSet\":\"TYPE5SET\",\r\n \"rows\":360,\r\n \"name\":\"alertText2\"\r\n },\r\n {\r\n \"width\":1980,\r\n \"characterSet\":\"CID2SET\",\r\n \"rows\":960,\r\n \"name\":\"scrollableMessageBody\"\r\n },\r\n ],\r\n \"imageFields\":[\r\n {\r\n \"imageTypeSupported\":[\r\n \"GRAPHIC_JPEG\",\r\n \"AUDIO_AAC\"\r\n ],\r\n \"imageResolution\":{\r\n \"resolutionWidth\":640,\r\n \"resolutionHeight\":480\r\n },\r\n \"name\":\"menuIcon\"\r\n },\r\n {\r\n \"imageTypeSupported\":[\r\n \"BINARY\",\r\n \"AUDIO_WAVE\"\r\n ],\r\n \"imageResolution\":{\r\n \"resolutionWidth\":320,\r\n \"resolutionHeight\":240\r\n },\r\n \"name\":\"graphic\"\r\n }\r\n ],\r\n \"graphicSupported\":true,\r\n \"screenParams\":{\r\n \"resolution\":{\r\n \"resolutionWidth\":1200,\r\n \"resolutionHeight\":800\r\n },\r\n \"touchEventAvailable\":{\r\n \"pressAvailable\":true,\r\n \"multiTouchAvailable\":false,\r\n \"doublePressAvailable\":true\r\n }\r\n },\r\n \"templatesAvailable\":[\r\n \"Template 1\",\r\n \"Template 2\",\r\n \"Template 3\"\r\n ],\r\n \"numCustomPresetsAvailable\":5\r\n },\r\n \"hmiDisplayLanguage\":\"ES-ES\",\r\n \"softButtonCapabilities\":[\r\n {\r\n \"imageSupported\":false,\r\n \"shortPressAvailable\":true,\r\n \"longPressAvailable\":false,\r\n \"upDownAvailable\":true\r\n },\r\n {\r\n \"imageSupported\":true,\r\n \"shortPressAvailable\":false,\r\n \"longPressAvailable\":true,\r\n \"upDownAvailable\":false\r\n }\r\n ],\r\n \"presetBankCapabilities\":{\r\n \"OnScreenPresetsAvailable\":false\r\n },\r\n \"bulkData\":[\r\n 0,\r\n 1,\r\n 2\r\n ]\r\n }\r\n }\r\n}";
+ System.out.print(rawRai);
+ System.out.print("\n");
+
+ try {
+ JSONObject jsonObject = new JSONObject(rawRai);
+ if(jsonObject != null){
+ System.out.print("The package was accepted");
+
+ }else{
+ System.out.print("The system is down");
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ }
+ public static void attemptSdlManager(){
+ SdlManager.Builder builder = new SdlManager.Builder("234523452345234", "JavaChip", new SdlManagerListener() {
+ @Override
+ public void onStart(SdlManager manager) {
+ Log.i(TAG, "OnStart");
+ manager.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, new OnRPCNotificationListener() {
+ @Override
+ public void onNotified(RPCNotification notification) {
+ Log.i(TAG, "on notified");
+ OnHMIStatus hmiStatus = (OnHMIStatus)notification;
+ if(HMILevel.HMI_FULL.equals(hmiStatus.getHmiLevel())) {
+ if (hmiStatus.getFirstRun()) {
+ //TOD DO a show
+ Show show = new Show();
+ show.setMainField1("There's snake in my boots");
+ show.setMainField2("YEET THAT SUCKER!");
+ manager.sendRPC(show);
+ Log.i(TAG, "Attempting sending show");
+
+
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onDestroy(SdlManager manager) {
+ Log.i(TAG, "onDestroy");
+
+ }
+
+ @Override
+ public void onError(SdlManager manager, String info, Exception e) {
+ Log.i(TAG, "OnError");
+ }
+ });
+ //FIXME have to add websocket setting
+ SdlManager manager = builder.build();
+ manager.start();
+
+
+ }
+
+ public static void startSdl(){
+ System.out.println("Hello World!");
+
+ Thread thread = new Thread(new Runnable() {
+ boolean end = false;
+
+ @Override
+ public void run() {
+ LifecycleManager.AppConfig config = new LifecycleManager.AppConfig();
+ config.appID = "234523452345234";
+ config.appName = "JavaChip";
+
+ WebSocketServerConfig serverConfig = new WebSocketServerConfig(5679,0);
+ LifecycleManager lifer = new LifecycleManager(config, serverConfig, new LifecycleManager.LifecycleListener() {
+ @Override
+ public void onProxyConnected(LifecycleManager lifeCycleManager) {
+ System.out.print("On proxy CONNECTED");
+
+ lifeCycleManager.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, new OnRPCNotificationListener() {
+ @Override
+ public void onNotified(RPCNotification notification) {
+ Log.i(TAG, "on notified");
+ OnHMIStatus hmiStatus = (OnHMIStatus)notification;
+
+ if(HMILevel.HMI_FULL.equals(hmiStatus.getHmiLevel())) {
+ if (true || hmiStatus.getFirstRun()) {
+ //TOD DO a show
+ Show show = new Show();
+ show.setMainField1("There's snake in my boots");
+ show.setMainField2("YEET THAT SUCKER!");
+ lifeCycleManager.sendRpc(show);
+
+
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onProxyClosed(LifecycleManager lifeCycleManager, String info, Exception e, SdlDisconnectedReason reason) {
+ System.out.print("On proxy CLOSED");
+ end = true;
+ }
+
+ @Override
+ public void onServiceEnded(LifecycleManager lifeCycleManager, OnServiceEnded serviceEnded) {
+ System.out.print("On service ENDED");
+
+ }
+
+ @Override
+ public void onServiceNACKed(LifecycleManager lifeCycleManager, OnServiceNACKed serviceNACKed) {
+ System.out.print("On service NAKed");
+
+ }
+
+ @Override
+ public void onError(LifecycleManager lifeCycleManager, String info, Exception e) {
+ System.out.print("OnError " + info);
+
+ }
+ });
+ lifer.start();
+ while(true || !end){
+
+ }
+ }
+
+ });
+
+ thread.start();
+
+ }
+}