summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rwxr-xr-xandroid/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlReceiver.java13
-rw-r--r--android/sdl_android/build.gradle6
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java4
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java784
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlArtworkTests.java (renamed from android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/SdlArtworkTests.java)0
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlFileTests.java136
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/RpcConverterTest.java3
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManagerTests.java105
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java100
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java157
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperationTests.java99
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java6
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java71
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java2
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java473
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppInterfaceUnregisteredReasonTests.java4
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MaintenanceModeStatusTests.java111
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MessageTypeTests.java94
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/PermissionStatusTests.java111
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java4
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TimerModeTests.java107
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VehicleDataActiveStatusTests.java115
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/video/VideoStreamingParametersTest.java60
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/RSVTestCase.java35
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java35
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java13
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java14
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java189
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java214
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java36
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java51
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCRequestFactory.java2
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java17
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java8
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java197
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java2
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java25
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java3
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java42
-rw-r--r--android/sdl_android/src/main/res/values/sdl.xml2
40 files changed, 3148 insertions, 302 deletions
diff --git a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlReceiver.java b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlReceiver.java
index 09cf35a82..bedeb0a39 100755
--- a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlReceiver.java
+++ b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlReceiver.java
@@ -7,11 +7,9 @@ import android.util.Log;
import com.smartdevicelink.transport.SdlBroadcastReceiver;
import com.smartdevicelink.transport.SdlRouterService;
-import com.smartdevicelink.transport.TransportConstants;
public class SdlReceiver extends SdlBroadcastReceiver {
private static final String TAG = "SdlBroadcastReciever";
- public static final String RECONNECT_LANG_CHANGE = "RECONNECT_LANG_CHANGE";
@Override
public void onSdlEnabled(Context context, Intent intent) {
@@ -36,16 +34,5 @@ public class SdlReceiver extends SdlBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); // Required if overriding this method
-
- if (intent != null) {
- String action = intent.getAction();
- if (action != null){
- if(action.equalsIgnoreCase(TransportConstants.START_ROUTER_SERVICE_ACTION)) {
- if (intent.getBooleanExtra(RECONNECT_LANG_CHANGE, false)) {
- onSdlEnabled(context, intent);
- }
- }
- }
- }
}
} \ No newline at end of file
diff --git a/android/sdl_android/build.gradle b/android/sdl_android/build.gradle
index aa5f96b1f..08ff0d4e2 100644
--- a/android/sdl_android/build.gradle
+++ b/android/sdl_android/build.gradle
@@ -3,11 +3,11 @@ import org.apache.tools.ant.taskdefs.condition.Os
android {
- compileSdkVersion 28
+ compileSdkVersion 29
defaultConfig {
minSdkVersion 8
- targetSdkVersion 28
- versionCode 11
+ targetSdkVersion 29
+ versionCode 12
versionName new File(projectDir.path, ('/../../VERSION')).text.trim()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
resValue "string", "SDL_LIB_VERSION", '\"' + versionName + '\"'
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java
index 5c6656bf9..63917067e 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java
@@ -25,6 +25,7 @@ import com.smartdevicelink.test.Test;
import com.smartdevicelink.transport.BaseTransportConfig;
import com.smartdevicelink.transport.TCPTransportConfig;
+import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -60,6 +61,8 @@ public class SdlManagerTests extends AndroidTestCase2 {
public void setUp() throws Exception{
super.setUp();
+ mTestContext = Mockito.mock(Context.class);
+
// set transport
transport = new TCPTransportConfig(TCP_PORT, DEV_MACHINE_IP_ADDRESS, true);
@@ -125,6 +128,7 @@ public class SdlManagerTests extends AndroidTestCase2 {
builder.setLockScreenConfig(lockScreenConfig);
builder.setMinimumProtocolVersion(Test.GENERAL_VERSION);
builder.setMinimumRPCVersion(Test.GENERAL_VERSION);
+ builder.setContext(mTestContext);
manager = builder.build();
// mock SdlProxyBase and set it manually
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java
index b1a0ba26e..3e6d160d5 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java
@@ -8,8 +8,11 @@ import com.smartdevicelink.managers.BaseSubManager;
import com.smartdevicelink.managers.CompletionListener;
import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
import com.smartdevicelink.managers.file.filetypes.SdlFile;
+import com.smartdevicelink.proxy.RPCMessage;
import com.smartdevicelink.proxy.RPCRequest;
import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.DeleteFile;
+import com.smartdevicelink.proxy.rpc.DeleteFileResponse;
import com.smartdevicelink.proxy.rpc.ListFiles;
import com.smartdevicelink.proxy.rpc.ListFilesResponse;
import com.smartdevicelink.proxy.rpc.PutFile;
@@ -30,6 +33,8 @@ import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
/**
* This is a unit test class for the SmartDeviceLink library manager class :
@@ -57,24 +62,64 @@ public class FileManagerTests extends AndroidTestCase2 {
super.tearDown();
}
- private Answer<Void> onListFilesSuccess = new Answer<Void>() {
+ private Answer<Void> onPutFileFailureOnError = new Answer<Void>() {
@Override
- public Void answer(InvocationOnMock invocation) {
+ public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
RPCRequest message = (RPCRequest) args[0];
- if(message instanceof ListFiles){
+ if (message instanceof PutFile) {
int correlationId = message.getCorrelationID();
- ListFilesResponse listFilesResponse = new ListFilesResponse();
- listFilesResponse.setFilenames(Test.GENERAL_STRING_LIST);
- listFilesResponse.setSpaceAvailable(Test.GENERAL_INT);
- listFilesResponse.setSuccess(true);
- message.getOnRPCResponseListener().onResponse(correlationId, listFilesResponse);
+ Result resultCode = Result.REJECTED;
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(false);
+ message.getOnRPCResponseListener().onError(correlationId, resultCode, "Binary data empty");
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onSendRequestsFailOnError = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
+ OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
+ if (rpcs.get(0) instanceof PutFile) {
+ Result resultCode = Result.REJECTED;
+ for (RPCRequest message : rpcs) {
+ int correlationId = message.getCorrelationID();
+ listener.addCorrelationId(correlationId);
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(true);
+ listener.onError(correlationId, resultCode, "Binary data empty");
+ }
+ listener.onFinished();
}
return null;
}
};
- private Answer<Void> onListFilesFailure = new Answer<Void>() {
+ private Answer<Void> onListFileUploadSuccess = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
+ OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
+ if (rpcs.get(0) instanceof PutFile) {
+ for (RPCRequest message : rpcs) {
+ int correlationId = message.getCorrelationID();
+ listener.addCorrelationId(correlationId);
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(true);
+ listener.onResponse(correlationId, putFileResponse);
+ }
+ listener.onFinished();
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onListFilesSuccess = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
@@ -82,7 +127,9 @@ public class FileManagerTests extends AndroidTestCase2 {
if(message instanceof ListFiles){
int correlationId = message.getCorrelationID();
ListFilesResponse listFilesResponse = new ListFilesResponse();
- listFilesResponse.setSuccess(false);
+ listFilesResponse.setFilenames(Test.GENERAL_STRING_LIST);
+ listFilesResponse.setSpaceAvailable(Test.GENERAL_INT);
+ listFilesResponse.setSuccess(true);
message.getOnRPCResponseListener().onResponse(correlationId, listFilesResponse);
}
return null;
@@ -120,20 +167,71 @@ public class FileManagerTests extends AndroidTestCase2 {
}
};
- private Answer<Void> onSendRequestsSuccess = new Answer<Void>() {
+ private Answer<Void> onListDeleteRequestSuccess = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
- if(rpcs.get(0) instanceof PutFile){
- for(RPCRequest message : rpcs){
+ if (rpcs.get(0) instanceof DeleteFile) {
+ for (RPCRequest message : rpcs) {
+ int correlationId = message.getCorrelationID();
+ listener.addCorrelationId(correlationId);
+ DeleteFileResponse deleteFileResponse = new DeleteFileResponse();
+ deleteFileResponse.setSuccess(true);
+ listener.onResponse(correlationId, deleteFileResponse);
+ }
+ listener.onFinished();
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onListDeleteRequestFail = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
+ OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
+ if (rpcs.get(0) instanceof DeleteFile) {
+ Result resultCode = Result.REJECTED;
+ for (RPCRequest message : rpcs) {
+ int correlationId = message.getCorrelationID();
+ listener.addCorrelationId(correlationId);
+ DeleteFileResponse deleteFileResponse = new DeleteFileResponse();
+ deleteFileResponse.setSuccess(true);
+ listener.onError(correlationId, resultCode, "Binary data empty");
+ }
+ listener.onFinished();
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onSendRequestsFailPartialOnError = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
+ OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
+ if (rpcs.get(0) instanceof PutFile) {
+ Result resultCode = Result.REJECTED;
+ boolean flip = false;
+ for (RPCRequest message : rpcs) {
int correlationId = message.getCorrelationID();
listener.addCorrelationId(correlationId);
PutFileResponse putFileResponse = new PutFileResponse();
- putFileResponse.setSuccess(true);
- listener.onResponse(correlationId, putFileResponse);
+ if (flip) {
+ putFileResponse.setSuccess(true);
+ flip = false;
+ listener.onResponse(correlationId, putFileResponse);
+ } else {
+ flip = true;
+ putFileResponse.setSuccess(false);
+ listener.onError(correlationId, resultCode, "Binary data empty");
+ }
}
+ listener.onFinished();
}
return null;
}
@@ -141,46 +239,231 @@ public class FileManagerTests extends AndroidTestCase2 {
// TESTS
- public void testInitializationSuccess(){
- ISdl internalInterface = mock(ISdl.class);
+ /**
+ * Test deleting list of files, success
+ */
+ public void testDeleteRemoteFilesWithNamesSuccess(){
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListDeleteRequestSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ final List<String> fileNames = new ArrayList<>();
+ fileNames.add("Julian");
+ fileNames.add("Jake");
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setFileRetryCount(2);
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ final FileManager fileManager = new FileManager(internalInterface,mTestContext,fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
assertTrue(success);
- assertEquals(fileManager.getState(), BaseSubManager.READY);
- assertEquals(fileManager.getRemoteFileNames(), Test.GENERAL_STRING_LIST);
- assertEquals(Test.GENERAL_INT, fileManager.getBytesAvailable());
+ fileManager.deleteRemoteFilesWithNames(fileNames, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertTrue(errors == null);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Test deleting list of files, fail
+ */
+ public void testDeleteRemoteFilesWithNamesFail(){
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListDeleteRequestFail).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ final List<String> fileNames = new ArrayList<>();
+ fileNames.add("Julian");
+ fileNames.add("Jake");
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setFileRetryCount(2);
+
+ final FileManager fileManager = new FileManager(internalInterface,mTestContext,fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ fileManager.deleteRemoteFilesWithNames(fileNames, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertTrue(errors.size() == 2);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Test reUploading failed file
+ */
+ public void testFileUploadRetry(){
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onPutFileFailureOnError).when(internalInterface).sendRPC(any(PutFile.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setFileRetryCount(2);
+
+ validFile.setType(FileType.AUDIO_MP3);
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext,fileManagerConfig);
+
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ fileManager.uploadFile(validFile, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertFalse(success);
+ }
+ });
}
});
+ verify(internalInterface, times(4)).sendRPC(any(RPCMessage.class));
}
- public void testInitializationFailure(){
+ /**
+ * Test reUploading failed Artwork
+ */
+ public void testArtworkUploadRetry(){
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onPutFileFailureOnError).when(internalInterface).sendRPC(any(PutFile.class));
+
+ final SdlFile validFile2 = new SdlFile();
+ validFile2.setName(Test.GENERAL_STRING + "2");
+ validFile2.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile2.setPersistent(false);
+ validFile2.setType(FileType.GRAPHIC_PNG);
+
+ final SdlFile validFile3 = new SdlFile();
+ validFile3.setName(Test.GENERAL_STRING + "3");
+ validFile3.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile3.setPersistent(false);
+ validFile3.setType(FileType.GRAPHIC_BMP);
+
+ validFile.setType(FileType.GRAPHIC_JPEG);
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setArtworkRetryCount(2);
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext,fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ fileManager.uploadFile(validFile, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertFalse(success);
+ verify(internalInterface, times(4)).sendRPC(any(RPCMessage.class));
+ }
+ });
+
+ fileManager.uploadFile(validFile2, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertFalse(success);
+ verify(internalInterface, times(7)).sendRPC(any(RPCMessage.class));
+ }
+ });
+
+ fileManager.uploadFile(validFile3, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertFalse(success);
+ }
+ });
+ }
+ });
+ verify(internalInterface, times(10)).sendRPC(any(RPCMessage.class));
+ }
+
+ /**
+ * Test retry uploading failed list of files
+ */
+ public void testListFilesUploadRetry(){
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onSendRequestsFailOnError).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ SdlFile validFile2 = new SdlFile();
+ validFile2.setName(Test.GENERAL_STRING + "2");
+ validFile2.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile2.setPersistent(false);
+ validFile2.setType(FileType.GRAPHIC_JPEG);
+
+ validFile.setType(FileType.AUDIO_WAVE);
+
+ final List<SdlFile> list = new ArrayList<>();
+ list.add(validFile);
+ list.add(validFile2);
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setArtworkRetryCount(2);
+ fileManagerConfig.setFileRetryCount(4);
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext,fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ fileManager.uploadFiles(list, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertTrue(errors.size() == 2); // We need to make sure it kept track of both Files
+ }
+ });
+
+ }
+ });
+ verify(internalInterface, times(5)).sendRequests(any(List.class),any(OnMultipleRequestListener.class));
+ }
+
+ /**
+ * Testing the initialization of FileManager
+ */
+ public void testInitializationSuccess() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesFailure).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
- assertFalse(success);
- assertEquals(fileManager.getState(), BaseSubManager.ERROR);
- assertEquals(BaseFileManager.SPACE_AVAILABLE_MAX_VALUE, fileManager.getBytesAvailable());
+ assertTrue(success);
+ assertEquals(fileManager.getState(), BaseSubManager.READY);
+ assertEquals(fileManager.getRemoteFileNames(), Test.GENERAL_STRING_LIST);
+ assertEquals(Test.GENERAL_INT, fileManager.getBytesAvailable());
}
});
}
- public void testFileUploadSuccess(){
+ /**
+ * Test file upload, success
+ */
+ public void testFileUploadSuccess() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
- doAnswer(onPutFileSuccess).when(internalInterface).sendRPCRequest(any(PutFile.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onPutFileSuccess).when(internalInterface).sendRPC(any(PutFile.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -189,22 +472,26 @@ public class FileManagerTests extends AndroidTestCase2 {
@Override
public void onComplete(boolean success) {
assertTrue(success);
- assertTrue(fileManager.getRemoteFileNames().contains(validFile.getName()));
- assertTrue(fileManager.hasUploadedFile(validFile));
- assertEquals(Test.GENERAL_INT, fileManager.getBytesAvailable());
}
});
}
});
+ assertTrue(fileManager.getRemoteFileNames().contains(validFile.getName()));
+ assertTrue(fileManager.hasUploadedFile(validFile));
+ assertEquals(Test.GENERAL_INT, fileManager.getBytesAvailable());
}
- public void testFileUploadFailure(){
+ /**
+ * Testing failed file upload.
+ */
+ public void testFileUploadFailure() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
- doAnswer(onPutFileFailure).when(internalInterface).sendRPCRequest(any(PutFile.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onPutFileFailure).when(internalInterface).sendRPC(any(PutFile.class));
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -221,12 +508,16 @@ public class FileManagerTests extends AndroidTestCase2 {
});
}
- public void testFileUploadForStaticIcon(){
+ /**
+ * Testing uploadFile for a staticIcon, verifying that it doesn't actually upload.
+ */
+ public void testFileUploadForStaticIcon() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -240,14 +531,82 @@ public class FileManagerTests extends AndroidTestCase2 {
});
}
});
+ verify(internalInterface, times(1)).sendRPC(any(RPCMessage.class));
+ }
+
+ /**
+ * Testing uploadFiles for staticIcons, verifying that it doesn't actually upload.
+ */
+ public void testMultipleFileUploadsForStaticIcon() {
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListFileUploadSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ SdlArtwork artwork = new SdlArtwork(StaticIconName.ALBUM);
+ SdlArtwork artwork2 = new SdlArtwork(StaticIconName.FILENAME);
+ List<SdlArtwork> testStaticIconUpload = new ArrayList<>();
+ testStaticIconUpload.add(artwork);
+ testStaticIconUpload.add(artwork2);
+ fileManager.uploadFiles(testStaticIconUpload, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertTrue(errors == null);
+ }
+ });
+ }
+ });
+ verify(internalInterface, times(0)).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
}
- public void testInvalidSdlFileInput(){
+ /**
+ * Testing uploadFiles for static icons and nonStatic icons in the same list.
+ */
+ public void testMultipleFileUploadsForPartialStaticIcon() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListFileUploadSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ SdlArtwork artwork = new SdlArtwork(StaticIconName.ALBUM);
+ SdlArtwork artwork2 = new SdlArtwork(StaticIconName.FILENAME);
+ List<SdlFile> testFileuploads = new ArrayList<>();
+ testFileuploads.add(artwork);
+ testFileuploads.add(artwork2);
+ testFileuploads.add(validFile);
+ fileManager.uploadFiles(testFileuploads, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertTrue(errors == null);
+ }
+ });
+ }
+ });
+ verify(internalInterface, times(1)).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ }
+
+ /**
+ * Test to make sure you cannot upload an SdlFile with invalid data
+ */
+ public void testInvalidSdlFileInput() {
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -278,6 +637,12 @@ public class FileManagerTests extends AndroidTestCase2 {
});
}
+ /**
+ * Used to try and upload SdlFiles with invalid data, throw an assert error if file uploads
+ *
+ * @param fileManager - FileManager used to manage and upload files
+ * @param sdlFile - SdlFile with invalid data to test uploading
+ */
private void checkForUploadFailure(FileManager fileManager, SdlFile sdlFile){
boolean error = false;
@@ -293,6 +658,10 @@ public class FileManagerTests extends AndroidTestCase2 {
assertTrue(error);
}
+ /**
+ * Test Invalid SdlArtWork FileTypes
+ * SdlArtwork FileTypes can only be: GRAPHIC_BMP, GRAPHIC_PNG or GRAPHIC_JPEG
+ */
public void testInvalidSdlArtworkInput(){
SdlArtwork sdlArtwork = new SdlArtwork();
// Set invalid type
@@ -311,148 +680,101 @@ public class FileManagerTests extends AndroidTestCase2 {
}
}
- public void testMultipleFileUploadThenDeleteSuccess(){
+ /**
+ * Test Multiple File Uploads, success
+ */
+ public void testMultipleFileUpload() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
- doAnswer(onSendRequestsSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListFileUploadSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
assertTrue(success);
- int fileNum = 1;
final List<SdlFile> filesToUpload = new ArrayList<>();
- SdlFile sdlFile = new SdlFile();
- sdlFile.setName("file" + fileNum++);
- Uri uri = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl");
- sdlFile.setUri(uri);
- filesToUpload.add(sdlFile);
+ filesToUpload.add(validFile);
- sdlFile = new SdlFile();
- sdlFile.setName("file" + fileNum++);
- sdlFile.setResourceId(com.smartdevicelink.test.R.drawable.ic_sdl);
- filesToUpload.add(sdlFile);
+ SdlFile validFile2 = new SdlFile();
+ validFile2.setName(Test.GENERAL_STRING + "2");
+ validFile2.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile2.setPersistent(false);
+ validFile2.setType(FileType.GRAPHIC_JPEG);
+ filesToUpload.add(validFile2);
- fileManager.uploadFiles(filesToUpload,
- new MultipleFileCompletionListener() {
- @Override
- public void onComplete(Map<String, String> errors) {
- assertNull(errors);
- List <String> uploadedFileNames = fileManager.getRemoteFileNames();
- for(SdlFile file : filesToUpload){
- assertTrue(uploadedFileNames.contains(file.getName()));
- }
- fileManager.deleteRemoteFilesWithNames(uploadedFileNames, new MultipleFileCompletionListener() {
- @Override
- public void onComplete(Map<String, String> errors) {
- assertNull(errors);
- List <String> uploadedFileNames = fileManager.getRemoteFileNames();
- for(SdlFile file : filesToUpload){
- assertFalse(uploadedFileNames.contains(file.getName()));
- }
- }
- });
- }
- });
+ fileManager.uploadFiles(filesToUpload, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertNull(errors);
+ }
+ });
}
});
}
- public void testMultipleFileUploadPartialFailure(){
- final String failureReason = "No space available";
-
+ /**
+ * Testing uploading multiple files with some failing.
+ */
+ public void testMultipleFileUploadPartialFailure() {
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onSendRequestsFailPartialOnError).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
- Answer<Void> onSendRequestsFailure = new Answer<Void>() {
- private int responseNum = 0;
- @Override
- public Void answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- List<RPCRequest> rpcs = (List<RPCRequest>) args[0];
- OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
- if(rpcs.get(0) instanceof PutFile){
- for(RPCRequest message : rpcs){
- int correlationId = message.getCorrelationID();
- listener.addCorrelationId(correlationId);
- PutFileResponse putFileResponse = new PutFileResponse();
- if(responseNum++ % 2 == 0){
- listener.onError(correlationId, Result.OUT_OF_MEMORY, failureReason);
- }else{
- putFileResponse.setSuccess(true);
- listener.onResponse(correlationId, putFileResponse);
- }
- }
- }
- return null;
- }
- };
- doAnswer(onSendRequestsFailure).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ SdlFile validFile2 = new SdlFile();
+ validFile2.setName(Test.GENERAL_STRING + "2");
+ validFile2.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile2.setPersistent(false);
+ validFile2.setType(FileType.GRAPHIC_JPEG);
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
- fileManager.start(new CompletionListener() {
- @Override
- public void onComplete(boolean success) {
- assertTrue(success);
- final String baseFileName = "file";
- int fileNum = 0;
- final List<SdlFile> filesToUpload = new ArrayList<>();
- SdlFile sdlFile = new SdlFile();
- sdlFile.setName(baseFileName + fileNum++);
- Uri uri = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl");
- sdlFile.setUri(uri);
- filesToUpload.add(sdlFile);
+ SdlFile validFile3 = new SdlFile();
+ validFile3.setName(Test.GENERAL_STRING + "3");
+ validFile3.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile3.setPersistent(false);
+ validFile3.setType(FileType.GRAPHIC_JPEG);
- sdlFile = new SdlFile();
- sdlFile.setName(baseFileName + fileNum++);
- sdlFile.setResourceId(com.smartdevicelink.test.R.drawable.ic_sdl);
- filesToUpload.add(sdlFile);
+ validFile.setType(FileType.AUDIO_WAVE);
- sdlFile = new SdlFile();
- sdlFile.setName(baseFileName + fileNum++);
- sdlFile.setFileData(Test.GENERAL_BYTE_ARRAY);
- sdlFile.setPersistent(true);
- sdlFile.setType(FileType.BINARY);
- filesToUpload.add(sdlFile);
+ final List<SdlFile> filesToUpload = new ArrayList<>();
+ filesToUpload.add(validFile);
+ filesToUpload.add(validFile2);
+ filesToUpload.add(validFile3);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setArtworkRetryCount(0);
+ fileManagerConfig.setFileRetryCount(0);
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
fileManager.uploadFiles(filesToUpload,
new MultipleFileCompletionListener() {
@Override
public void onComplete(Map<String, String> errors) {
- assertNotNull(errors);
- for(int i = 0; i < filesToUpload.size(); i++){
- if(i % 2 == 0){
- assertTrue(errors.containsKey(filesToUpload.get(i).getName()));
- assertEquals(FileManager.buildErrorString(Result.OUT_OF_MEMORY,
- failureReason), errors.get(filesToUpload.get(i).getName()));
- }else{
- assertFalse(errors.containsKey(filesToUpload.get(i).getName()));
- }
- }
- List <String> uploadedFileNames = fileManager.getRemoteFileNames();
- for(int i = 0; i < filesToUpload.size(); i++){
- if(i % 2 == 0){
- assertFalse(uploadedFileNames.contains(filesToUpload.get(i).getName()));
- }else{
- assertTrue(uploadedFileNames.contains(filesToUpload.get(i).getName()));
- }
- }
+ assertTrue(errors.size() == 2);
}
});
}
});
+ assertFalse(fileManager.hasUploadedFile(validFile) && fileManager.hasUploadedFile(validFile3));
+ assertTrue(fileManager.hasUploadedFile(validFile2));
}
+ /**
+ * Testing uploading multiple SdlArtwork files.
+ */
public void testMultipleArtworkUploadSuccess(){
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
- doAnswer(onSendRequestsSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListFileUploadSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -488,16 +810,20 @@ public class FileManagerTests extends AndroidTestCase2 {
});
}
+ /**
+ * Testing uploading persistent SdlFile
+ */
public void testPersistentFileUploaded(){
ISdl internalInterface = mock(ISdl.class);
- doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
final SdlFile file = new SdlFile();
file.setName(Test.GENERAL_STRING_LIST.get(0));
file.setPersistent(true);
- final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
fileManager.start(new CompletionListener() {
@Override
public void onComplete(boolean success) {
@@ -505,4 +831,154 @@ public class FileManagerTests extends AndroidTestCase2 {
}
});
}
+
+ /**
+ * Test FileManagerConfig
+ */
+ public void testFileManagerConfig() {
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setFileRetryCount(2);
+ fileManagerConfig.setArtworkRetryCount(2);
+ assertEquals(fileManagerConfig.getArtworkRetryCount(), 2);
+ assertEquals(fileManagerConfig.getFileRetryCount(), 2);
+ }
+
+ /**
+ * Tests overwrite property for uploading a file.
+ * Checks to make sure file does not overwrite itself if overwrite property is set to false
+ */
+ public void testOverwriteFileProperty() {
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onPutFileSuccess).when(internalInterface).sendRPC(any(PutFile.class));
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ fileManager.uploadFile(validFile, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ validFile.setOverwrite(false);
+ fileManager.uploadFile(validFile, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ }
+ });
+
+ }
+ });
+ }
+ });
+ verify(internalInterface, times(2)).sendRPC(any(RPCMessage.class));
+ }
+
+ /**
+ * Tests overwrite property for uploading a list of files.
+ * Checks to make sure files do not overwrite themselves if overwrite property is set to false.
+ */
+ public void testOverWriteFilePropertyListFiles() {
+ final ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPC(any(ListFiles.class));
+ doAnswer(onListFileUploadSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ final SdlFile validFile2 = new SdlFile();
+ validFile2.setName(Test.GENERAL_STRING + "2");
+ validFile2.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile2.setPersistent(false);
+ validFile2.setType(FileType.GRAPHIC_JPEG);
+
+ final List<SdlFile> list = new ArrayList<>();
+ list.add(validFile);
+ list.add(validFile2);
+
+ FileManagerConfig fileManagerConfig = new FileManagerConfig();
+ fileManagerConfig.setArtworkRetryCount(2);
+ fileManagerConfig.setFileRetryCount(4);
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext, fileManagerConfig);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ fileManager.uploadFiles(list, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ validFile.setOverwrite(false);
+ validFile2.setOverwrite(false);
+ fileManager.uploadFiles(list, new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertNull(errors);
+ }
+ });
+ }
+ });
+
+ }
+ });
+ verify(internalInterface, times(1)).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ }
+
+ /**
+ * Test custom overridden SdlFile equals method
+ */
+ public void testSdlFileEquals() {
+ // Case 1: object is null, assertFalse
+ SdlFile artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, true);
+ SdlFile artwork2 = null;
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 2 SoftButtonObjects are the same, assertTrue
+ assertTrue(artwork1.equals(artwork1));
+
+ // Case 3: object is not an instance of SoftButtonObject, assertFalse
+ assertFalse(artwork1.equals("Test"));
+
+ // Case 4: different StaticIcon status, assertFalse
+ artwork1.setStaticIcon(true);
+ artwork2 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, true);
+ artwork2.setStaticIcon(false);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 5: different Persistent status, assertFalse
+ artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ artwork2 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, true);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 6: different name, assertFalse
+ artwork2 = new SdlFile("image2", FileType.GRAPHIC_PNG, 1, false);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 7: different Uri
+ Uri uri1 = Uri.parse("testUri1");
+ Uri uri2 = Uri.parse("testUri2");
+ artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, uri1, false);
+ artwork2 = new SdlFile("image1", FileType.GRAPHIC_PNG, uri2, false);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 8: different FileData
+ artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ artwork2 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ byte[] GENERAL_BYTE_ARRAY2 = new byte[2];
+ artwork1.setFileData(Test.GENERAL_BYTE_ARRAY);
+ artwork2.setFileData(GENERAL_BYTE_ARRAY2);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 9 different FileType, assertFalse
+ artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ artwork2 = new SdlFile("image1", FileType.AUDIO_WAVE, 1, false);
+ assertFalse(artwork1.equals(artwork2));
+
+ // Case 10: they are equal, assertTrue
+ artwork1 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ artwork2 = new SdlFile("image1", FileType.GRAPHIC_PNG, 1, false);
+ assertTrue(artwork1.equals(artwork2));
+ }
} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/SdlArtworkTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlArtworkTests.java
index 395b06e27..395b06e27 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/SdlArtworkTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlArtworkTests.java
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlFileTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlFileTests.java
new file mode 100644
index 000000000..7dd13ec7c
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/filetypes/SdlFileTests.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2019 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.managers.file.filetypes;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.test.Test;
+
+public class SdlFileTests extends AndroidTestCase2 {
+
+ public void testConstructorWithNoParams() {
+ SdlFile sdlFile;
+
+ // Case 1 (Setting data)
+ sdlFile = new SdlFile();
+ sdlFile.setFileData(Test.GENERAL_BYTE_ARRAY);
+ assertEquals(sdlFile.getFileData(), Test.GENERAL_BYTE_ARRAY);
+ sdlFile.setName(null);
+ assertEquals(sdlFile.getName(), "e9800998ecf8427e");
+ sdlFile.setName(Test.GENERAL_STRING);
+ assertEquals(sdlFile.getName(), Test.GENERAL_STRING);
+ sdlFile.setType(Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile.getType(), Test.GENERAL_FILETYPE);
+ sdlFile.setPersistent(Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile.isPersistent(), Test.GENERAL_BOOLEAN);
+
+ // Case 2 (Setting resourceId)
+ sdlFile = new SdlFile();
+ sdlFile.setResourceId(Test.GENERAL_INTEGER);
+ assertEquals((Integer) sdlFile.getResourceId(), Test.GENERAL_INTEGER);
+ sdlFile.setName(null);
+ assertEquals(sdlFile.getName(), "ec9ebc78777cf40d");
+ sdlFile.setName(Test.GENERAL_STRING);
+ assertEquals(sdlFile.getName(), Test.GENERAL_STRING);
+ sdlFile.setType(Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile.getType(), Test.GENERAL_FILETYPE);
+ sdlFile.setPersistent(Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile.isPersistent(), Test.GENERAL_BOOLEAN);
+
+ // Case 3 (Setting URI)
+ sdlFile = new SdlFile();
+ sdlFile.setUri(Test.GENERAL_URI);
+ assertEquals(sdlFile.getUri(), Test.GENERAL_URI);
+ sdlFile.setName(null);
+ assertEquals(sdlFile.getName(), "d3467db131372140");
+ sdlFile.setName(Test.GENERAL_STRING);
+ assertEquals(sdlFile.getName(), Test.GENERAL_STRING);
+ sdlFile.setType(Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile.getType(), Test.GENERAL_FILETYPE);
+ sdlFile.setPersistent(Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile.isPersistent(), Test.GENERAL_BOOLEAN);
+ }
+
+ public void testConstructorWithResourceId() {
+ // Case1 (Set the name manually)
+ SdlFile sdlFile1 = new SdlFile(Test.GENERAL_STRING, Test.GENERAL_FILETYPE, Test.GENERAL_INTEGER, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile1.getName(), Test.GENERAL_STRING);
+ assertEquals(sdlFile1.getType(), Test.GENERAL_FILETYPE);
+ assertEquals((Integer) sdlFile1.getResourceId(), Test.GENERAL_INTEGER);
+ assertEquals(sdlFile1.isPersistent(), Test.GENERAL_BOOLEAN);
+
+ // Case2 (Let the library generate a name)
+ SdlFile sdlFile2 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_INTEGER, Test.GENERAL_BOOLEAN);
+ SdlFile sdlFile3 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_INTEGER, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile2.getName(), sdlFile3.getName());
+ assertEquals(sdlFile2.getName(), "ec9ebc78777cf40d");
+ assertEquals(sdlFile2.getType(), Test.GENERAL_FILETYPE);
+ assertEquals((Integer) sdlFile2.getResourceId(), Test.GENERAL_INTEGER);
+ assertEquals(sdlFile2.isPersistent(), Test.GENERAL_BOOLEAN);
+ }
+
+ public void testConstructorWithData() {
+ // Case1 (Set the name manually)
+ SdlFile sdlFile1 = new SdlFile(Test.GENERAL_STRING, Test.GENERAL_FILETYPE, Test.GENERAL_BYTE_ARRAY, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile1.getName(), Test.GENERAL_STRING);
+ assertEquals(sdlFile1.getType(), Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile1.getFileData(), Test.GENERAL_BYTE_ARRAY);
+ assertEquals(sdlFile1.isPersistent(), Test.GENERAL_BOOLEAN);
+
+ // Case2 (Let the library generate a name)
+ SdlFile sdlFile2 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_BYTE_ARRAY, Test.GENERAL_BOOLEAN);
+ SdlFile sdlFile3 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_BYTE_ARRAY, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile2.getName(), sdlFile3.getName());
+ assertEquals(sdlFile2.getName(), "e9800998ecf8427e");
+ assertEquals(sdlFile2.getType(), Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile2.getFileData(), Test.GENERAL_BYTE_ARRAY);
+ assertEquals(sdlFile2.isPersistent(), Test.GENERAL_BOOLEAN);
+ }
+
+ public void testConstructorWithUri() {
+ // Case1 (Set the name manually)
+ SdlFile sdlFile1 = new SdlFile(Test.GENERAL_STRING, Test.GENERAL_FILETYPE, Test.GENERAL_URI, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile1.getName(), Test.GENERAL_STRING);
+ assertEquals(sdlFile1.getType(), Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile1.getUri(), Test.GENERAL_URI);
+ assertEquals(sdlFile1.isPersistent(), Test.GENERAL_BOOLEAN);
+
+ // Case2 (Let the library generate a name)
+ SdlFile sdlFile2 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_URI, Test.GENERAL_BOOLEAN);
+ SdlFile sdlFile3 = new SdlFile(null, Test.GENERAL_FILETYPE, Test.GENERAL_URI, Test.GENERAL_BOOLEAN);
+ assertEquals(sdlFile2.getName(), sdlFile3.getName());
+ assertEquals(sdlFile2.getName(), "d3467db131372140");
+ assertEquals(sdlFile2.getType(), Test.GENERAL_FILETYPE);
+ assertEquals(sdlFile2.getUri(), Test.GENERAL_URI);
+ assertEquals(sdlFile2.isPersistent(), Test.GENERAL_BOOLEAN);
+ }
+}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/RpcConverterTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/RpcConverterTest.java
index 22e2cba2f..34b3f71aa 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/RpcConverterTest.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/RpcConverterTest.java
@@ -25,6 +25,7 @@ public class RpcConverterTest extends AndroidTestCase2 {
FunctionID[] functionIDs = FunctionID.values();
for(FunctionID functionID : functionIDs) {
switch (functionID){
+ case RESERVED:
case SYNC_P_DATA:
case ON_SYNC_P_DATA:
case ENCODED_SYNC_P_DATA:
@@ -54,6 +55,7 @@ public class RpcConverterTest extends AndroidTestCase2 {
rpcClassName.append(RPC_PACKAGE);
switch (functionID) {
+ case RESERVED:
case SYNC_P_DATA:
case ON_SYNC_P_DATA:
case ENCODED_SYNC_P_DATA:
@@ -91,6 +93,7 @@ public class RpcConverterTest extends AndroidTestCase2 {
for(FunctionID functionID : functionIDs){
switch (functionID){
+ case RESERVED:
case SYNC_P_DATA:
case ON_SYNC_P_DATA:
case ENCODED_SYNC_P_DATA:
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManagerTests.java
new file mode 100644
index 000000000..796f900d3
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManagerTests.java
@@ -0,0 +1,105 @@
+package com.smartdevicelink.managers.lockscreen;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.util.AndroidTools;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.Mockito;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+public class LockScreenDeviceIconManagerTests extends AndroidTestCase2 {
+
+ TemporaryFolder tempFolder = new TemporaryFolder();
+ private LockScreenDeviceIconManager lockScreenDeviceIconManager;
+ private static final String ICON_URL = "https://i.imgur.com/TgkvOIZ.png";
+ private static final String LAST_UPDATED_TIME = "lastUpdatedTime";
+ private static final String STORED_PATH = "storedPath";
+
+ public void setup() throws Exception {
+ super.setUp();
+ }
+
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testRetrieveIconShouldCallOnErrorTwiceWhenGivenURLThatCannotDownloadAndIconIsNotCached() {
+ final SharedPreferences sharedPrefs = Mockito.mock(SharedPreferences.class);
+ final Context context = Mockito.mock(Context.class);
+ final LockScreenDeviceIconManager.OnIconRetrievedListener listener = Mockito.mock(LockScreenDeviceIconManager.OnIconRetrievedListener.class);
+
+ Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
+ Mockito.when(sharedPrefs.getString(anyString(), (String) isNull())).thenReturn(null);
+
+ lockScreenDeviceIconManager = new LockScreenDeviceIconManager(context);
+ lockScreenDeviceIconManager.retrieveIcon("", listener);
+ verify(listener, times(2)).onError(anyString());
+ }
+
+ public void testRetrieveIconShouldCallOnImageOnImageRetrievedWithIconWhenIconUpdateTimeIsNullFromSharedPref() {
+ final SharedPreferences sharedPrefs = Mockito.mock(SharedPreferences.class);
+ final Context context = Mockito.mock(Context.class);
+ final LockScreenDeviceIconManager.OnIconRetrievedListener listener = Mockito.mock(LockScreenDeviceIconManager.OnIconRetrievedListener.class);
+
+ Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
+ Mockito.when(sharedPrefs.getString(anyString(), (String) isNull())).thenReturn(null);
+
+ lockScreenDeviceIconManager = new LockScreenDeviceIconManager(context);
+ lockScreenDeviceIconManager.retrieveIcon(ICON_URL, listener);
+ verify(listener, times(1)).onImageRetrieved((Bitmap) any());
+ }
+
+
+ public void testRetrieveIconShouldCallOnImageOnImageRetrievedWithIconWhenCachedIconExpired() {
+ final SharedPreferences sharedPrefs = Mockito.mock(SharedPreferences.class);
+ final Context context = Mockito.mock(Context.class);
+ final LockScreenDeviceIconManager.OnIconRetrievedListener listener = Mockito.mock(LockScreenDeviceIconManager.OnIconRetrievedListener.class);
+
+ Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
+ Mockito.when(sharedPrefs.getString(anyString(), (String) isNull())).thenReturn(daysToMillisecondsAsString(31));
+
+ lockScreenDeviceIconManager = new LockScreenDeviceIconManager(context);
+ lockScreenDeviceIconManager.retrieveIcon(ICON_URL, listener);
+ verify(listener, times(1)).onImageRetrieved((Bitmap) any());
+ }
+
+ public void testRetrieveIconShouldCallOnImageRetrievedWithIconWhenCachedIconIsUpToDate() {
+ final SharedPreferences sharedPrefs = Mockito.mock(SharedPreferences.class);
+ final Context context = Mockito.mock(Context.class);
+ final SharedPreferences.Editor sharedPrefsEditor = Mockito.mock(SharedPreferences.Editor.class);
+ final LockScreenDeviceIconManager.OnIconRetrievedListener listener = Mockito.mock(LockScreenDeviceIconManager.OnIconRetrievedListener.class);
+
+ Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
+ Mockito.when(sharedPrefs.getString(anyString(), (String) isNull())).thenReturn(daysToMillisecondsAsString(15));
+ Mockito.when(sharedPrefs.edit()).thenReturn(sharedPrefsEditor);
+ Mockito.when(sharedPrefsEditor.clear()).thenReturn(sharedPrefsEditor);
+
+ lockScreenDeviceIconManager = new LockScreenDeviceIconManager(context);
+ lockScreenDeviceIconManager.retrieveIcon(ICON_URL, listener);
+ verify(listener, times(1)).onImageRetrieved((Bitmap) any());
+ }
+
+ private String daysToMillisecondsAsString(int days) {
+ long milliSeconds = (long) days * 24 * 60 * 60 * 1000;
+ long previousDay = System.currentTimeMillis() - milliSeconds;
+ return String.valueOf(previousDay);
+ }
+}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java
index 514549080..93688f570 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java
@@ -9,6 +9,8 @@ import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
import com.smartdevicelink.protocol.enums.FunctionID;
import com.smartdevicelink.proxy.interfaces.ISdl;
import com.smartdevicelink.proxy.rpc.Image;
+import com.smartdevicelink.proxy.rpc.OnButtonEvent;
+import com.smartdevicelink.proxy.rpc.OnButtonPress;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.Show;
import com.smartdevicelink.proxy.rpc.SoftButton;
@@ -25,6 +27,7 @@ import com.smartdevicelink.test.Validator;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -305,4 +308,101 @@ public class SoftButtonManagerTests extends AndroidTestCase2 {
assertEquals("SoftButtonObject id doesn't match the expected value", 100, sbo4.getButtonId());
assertEquals("SoftButtonObject id doesn't match the expected value", 103, sbo5.getButtonId());
}
+
+ /**
+ * Test custom overridden softButtonObject equals method
+ */
+ public void testSoftButtonObjectEquals() {
+ SoftButtonObject softButtonObject1;
+ SoftButtonObject softButtonObject2;
+
+ SoftButtonObject.OnEventListener testOnEventList1 = new SoftButtonObject.OnEventListener() {
+ @Override
+ public void onPress(SoftButtonObject softButtonObject, OnButtonPress onButtonPress) {
+ }
+
+ @Override
+ public void onEvent(SoftButtonObject softButtonObject, OnButtonEvent onButtonEvent) {
+ }
+ };
+
+ SoftButtonObject.OnEventListener testOnEventList2 = new SoftButtonObject.OnEventListener() {
+ @Override
+ public void onPress(SoftButtonObject softButtonObject, OnButtonPress onButtonPress) {
+ }
+
+ @Override
+ public void onEvent(SoftButtonObject softButtonObject, OnButtonEvent onButtonEvent) {
+ }
+ };
+
+ // Case 1: object is null, assertFalse
+ softButtonObject1 = new SoftButtonObject("test", softButtonState1, null);
+ softButtonObject2 = null;
+ assertFalse(softButtonObject1.equals(softButtonObject2));
+
+ // Case 2 SoftButtonObjects are the same, assertTrue
+ assertTrue(softButtonObject1.equals(softButtonObject1));
+
+ // Case 3: object is not an instance of SoftButtonObject assertFalse
+ SdlArtwork artwork = new SdlArtwork("image1", FileType.GRAPHIC_PNG, 1, true);
+ assertFalse(softButtonObject1.equals(artwork));
+
+ // Case 4: SoftButtonObjectState List are not same size, assertFalse
+ List<SoftButtonState> softButtonStateList = new ArrayList<>();
+ List<SoftButtonState> softButtonStateList2 = new ArrayList<>();
+ softButtonStateList.add(softButtonState1);
+ softButtonStateList2.add(softButtonState1);
+ softButtonStateList2.add(softButtonState2);
+ softButtonObject1 = new SoftButtonObject("hi", softButtonStateList, "Hi", null);
+ softButtonObject2 = new SoftButtonObject("hi", softButtonStateList2, "Hi", null);
+ assertFalse(softButtonObject1.equals(softButtonObject2));
+
+ // Case 5: SoftButtonStates are not the same, assertFalse
+ softButtonObject1 = new SoftButtonObject("test", softButtonState1, null);
+ softButtonObject2 = new SoftButtonObject("test", softButtonState2, null);
+ assertFalse(softButtonObject1.equals(softButtonObject2));
+
+ // Case 6: SoftButtonObject names are not same, assertFalse
+ softButtonObject1 = new SoftButtonObject("test", softButtonState1, null);
+ softButtonObject2 = new SoftButtonObject("test23123", softButtonState1, null);
+ assertFalse(softButtonObject1.equals(softButtonObject2));
+
+ // Case 7: SoftButtonObject currentStateName not same, assertFalse
+ softButtonObject1 = new SoftButtonObject("hi", softButtonStateList, "Hi", null);
+ softButtonObject2 = new SoftButtonObject("hi", softButtonStateList, "Hi2", null);
+ assertFalse(softButtonObject1.equals(softButtonObject2));
+ }
+
+ /**
+ * Test custom overridden softButtonState equals method
+ */
+ public void testSoftButtonStateEquals() {
+ assertFalse(softButtonState1.equals(softButtonState2));
+ SdlArtwork artwork1 = new SdlArtwork("image1", FileType.GRAPHIC_PNG, 1, true);
+ SdlArtwork artwork2 = new SdlArtwork("image2", FileType.GRAPHIC_PNG, 1, true);
+
+ // Case 1: object is null, assertFalse
+ softButtonState1 = new SoftButtonState("object1-state1", "o1s1", artwork1);
+ softButtonState2 = null;
+ assertFalse(softButtonState1.equals(softButtonState2));
+
+ // Case 2 SoftButtonObjects are the same, assertTrue
+ assertTrue(softButtonState1.equals(softButtonState1));
+
+ // Case 3: object is not an instance of SoftButtonState, assertFalse
+ assertFalse(softButtonState1.equals(artwork1));
+
+ // Case 4: different artwork, assertFalse
+ softButtonState2 = new SoftButtonState("object1-state1", "o1s1", artwork2);
+ assertFalse(softButtonState1.equals(softButtonState2));
+
+ // Case 5: different name, assertFalse
+ softButtonState2 = new SoftButtonState("object1-state1 different name", "o1s1", artwork1);
+ assertFalse(softButtonState1.equals(softButtonState2));
+
+ // Case 6 they are equal, assertTrue
+ softButtonState2 = new SoftButtonState("object1-state1", "o1s1", artwork1);
+ assertTrue(softButtonState1.equals(softButtonState2));
+ }
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java
index 3597c33f5..8aa9ae8a8 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java
@@ -5,6 +5,7 @@ import android.net.Uri;
import com.smartdevicelink.AndroidTestCase2;
import com.smartdevicelink.managers.BaseSubManager;
+import com.smartdevicelink.managers.ManagerUtility;
import com.smartdevicelink.managers.file.FileManager;
import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
import com.smartdevicelink.proxy.interfaces.ISdl;
@@ -21,6 +22,7 @@ import com.smartdevicelink.proxy.rpc.enums.TextFieldName;
import org.json.JSONException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.mock;
@@ -90,6 +92,16 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 {
return windowCapability;
}
+ /**
+ * Used to simulate WindowCapability having no capabilities set
+ * @return windowCapability that has no capabilities set
+ */
+ private WindowCapability getNullVarWindowCapability() {
+
+ WindowCapability windowCapability = new WindowCapability();
+ return windowCapability;
+ }
+
public void testInstantiation(){
assertNull(textAndGraphicManager.getTextField1());
@@ -117,17 +129,21 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 {
assertNotNull(textAndGraphicManager.getBlankArtwork());
}
+ /**
+ * Test getting number of lines available to be set based off of windowCapability
+ */
public void testGetMainLines(){
// We want to test that the looping works. By default, it will return 4 if display cap is null
+ textAndGraphicManager.defaultMainWindowCapability = getNullVarWindowCapability();
// Null test
- assertEquals(textAndGraphicManager.getNumberOfLines(), 4);
+ assertEquals(0, ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(textAndGraphicManager.defaultMainWindowCapability));
// The tests.java class has an example of this, but we must build it to do what
// we need it to do. Build display cap w/ 3 main fields and test that it returns 3
textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(3);
- assertEquals(textAndGraphicManager.getNumberOfLines(), 3);
+ assertEquals(ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(textAndGraphicManager.defaultMainWindowCapability), 3);
}
public void testAssemble1Line(){
@@ -374,8 +390,141 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 {
Show inputShow = new Show();
- // Force it to return display with support for only 4 lines of text
textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(4);
+ TextField tx1 = new TextField();
+ TextField tx2 = new TextField();
+ TextField tx3 = new TextField();
+ TextField tx4 = new TextField();
+ TextField tx5 = new TextField();
+ TextField tx6 = new TextField();
+
+ tx1.setName(TextFieldName.mainField1);
+ tx2.setName(TextFieldName.mainField2);
+ tx3.setName(TextFieldName.mainField3);
+ tx4.setName(TextFieldName.mainField4);
+ tx5.setName(TextFieldName.mediaTrack);
+ tx6.setName(TextFieldName.templateTitle);
+
+ List<TextField> textFieldNames = Arrays.asList(tx1,tx2,tx3,tx4,tx5,tx6);
+ textAndGraphicManager.defaultMainWindowCapability.setTextFields(textFieldNames);
+
+ textAndGraphicManager.setMediaTrackTextField("HI");
+ textAndGraphicManager.setTitle("bye");
+
+ // Force it to return display with support for only 4 lines of text
+
+ textAndGraphicManager.setTextField1("It is");
+ textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY);
+
+ Show assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "");
+ assertEquals(assembledShow.getMainField3(), "");
+ assertEquals(assembledShow.getMainField4(), "");
+ assertEquals(assembledShow.getMediaTrack(), "HI");
+ assertEquals(assembledShow.getTemplateTitle(), "bye");
+
+ // test tags
+ MetadataTags tags = assembledShow.getMetadataTags();
+ List<MetadataType> tagsList = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ assertEquals(tags.getMainField1(), tagsList);
+
+ textAndGraphicManager.setTextField2("Wednesday");
+ textAndGraphicManager.setTextField2Type(MetadataType.CURRENT_TEMPERATURE);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "Wednesday");
+ assertEquals(assembledShow.getMainField3(), "");
+ assertEquals(assembledShow.getMainField4(), "");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ List<MetadataType> tagsList2 = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.CURRENT_TEMPERATURE);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+
+ textAndGraphicManager.setTextField3("My");
+ textAndGraphicManager.setTextField3Type(MetadataType.MEDIA_ALBUM);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "Wednesday");
+ assertEquals(assembledShow.getMainField3(), "My");
+ assertEquals(assembledShow.getMainField4(), "");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ List<MetadataType> tagsList3 = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList3.add(MetadataType.MEDIA_ALBUM);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+ assertEquals(tags.getMainField3(), tagsList3);
+
+ textAndGraphicManager.setTextField4("Dudes");
+ textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "Wednesday");
+ assertEquals(assembledShow.getMainField3(), "My");
+ assertEquals(assembledShow.getMainField4(), "Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ tagsList3 = new ArrayList<>();
+ List<MetadataType> tagsList4 = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList3.add(MetadataType.MEDIA_ALBUM);
+ tagsList4.add(MetadataType.MEDIA_STATION);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+ assertEquals(tags.getMainField3(), tagsList3);
+ assertEquals(tags.getMainField4(), tagsList4);
+
+ // try just setting line 1 and 4
+ textAndGraphicManager.setTextField2(null);
+ textAndGraphicManager.setTextField3(null);
+ textAndGraphicManager.setTextField2Type(null);
+ textAndGraphicManager.setTextField3Type(null);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "");
+ assertEquals(assembledShow.getMainField3(), "");
+ assertEquals(assembledShow.getMainField4(), "Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList4 = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList4.add(MetadataType.MEDIA_STATION);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField4(), tagsList4);
+ }
+
+ /**
+ * Testing if WindowCapability is null, TextFields should still update.
+ */
+ public void testAssemble4LinesNullWindowCapability() {
+
+ Show inputShow = new Show();
+
+ textAndGraphicManager.setMediaTrackTextField("HI");
+ textAndGraphicManager.setTitle("bye");
textAndGraphicManager.setTextField1("It is");
textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY);
@@ -386,6 +535,8 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 {
assertEquals(assembledShow.getMainField2(), "");
assertEquals(assembledShow.getMainField3(), "");
assertEquals(assembledShow.getMainField4(), "");
+ assertEquals(assembledShow.getMediaTrack(), "HI");
+ assertEquals(assembledShow.getTemplateTitle(), "bye");
// test tags
MetadataTags tags = assembledShow.getMetadataTags();
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperationTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperationTests.java
index b29863110..3fbfcada9 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperationTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperationTests.java
@@ -59,6 +59,9 @@ import static org.mockito.Mockito.mock;
public class PreloadChoicesOperationTests extends AndroidTestCase2 {
private PreloadChoicesOperation preloadChoicesOperation;
+ private PreloadChoicesOperation preloadChoicesOperationNullCapability;
+ private PreloadChoicesOperation preloadChoicesOperationEmptyCapability;
+
@Override
public void setUp() throws Exception{
@@ -72,37 +75,74 @@ public class PreloadChoicesOperationTests extends AndroidTestCase2 {
cellsToPreload.add(cell2);
ImageField imageField = new ImageField(ImageFieldName.choiceImage, Arrays.asList(FileType.GRAPHIC_PNG, FileType.GRAPHIC_JPEG));
+ ImageField imageField2 = new ImageField();
+ imageField2.setName(ImageFieldName.choiceSecondaryImage);
TextField textField = new TextField(TextFieldName.menuName, CharacterSet.CID1SET, 2, 2);
+ TextField textField2 = new TextField();
+ TextField textField3 = new TextField();
+
+ textField2.setName(TextFieldName.secondaryText);
+ textField3.setName(TextFieldName.tertiaryText);
+
+
WindowCapability windowCapability = new WindowCapability();
- windowCapability.setImageFields(Collections.singletonList(imageField));
+ windowCapability.setImageFields(Arrays.asList(imageField, imageField2));
windowCapability.setImageTypeSupported(Arrays.asList(ImageType.STATIC, ImageType.DYNAMIC));
- windowCapability.setTextFields(Collections.singletonList(textField));
+ windowCapability.setTextFields(Arrays.asList(textField, textField2, textField3));
ISdl internalInterface = mock(ISdl.class);
FileManager fileManager = mock(FileManager.class);
- preloadChoicesOperation = new PreloadChoicesOperation(internalInterface, fileManager, windowCapability, true, cellsToPreload, null);
+ preloadChoicesOperation = new PreloadChoicesOperation(internalInterface, fileManager, null, windowCapability, true, cellsToPreload, null);
}
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
+ /**
+ * Sets up PreloadChoicesOperation with WindowCapability being null
+ */
+ public void setUpNullWindowCapability() {
+
+ ChoiceCell cell1 = new ChoiceCell("cell 1");
+ ChoiceCell cell2 = new ChoiceCell("cell 2", null, Test.GENERAL_ARTWORK);
+ HashSet<ChoiceCell> cellsToPreload = new HashSet<>();
+ cellsToPreload.add(cell1);
+ cellsToPreload.add(cell2);
+
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
+ preloadChoicesOperationNullCapability = new PreloadChoicesOperation(internalInterface, fileManager, null, null, true, cellsToPreload, null);
}
- public void testHasTextFieldOfName(){
- boolean test = preloadChoicesOperation.hasTextFieldOfName(TextFieldName.secondaryText);
- assertFalse(test);
+ /**
+ * Sets up PreloadChoicesOperation with an Capability not being set
+ * certain imageFields and TextFields
+ */
+ public void setUpEmptyWindowCapability() {
+
+ ChoiceCell cell1 = new ChoiceCell("cell 1");
+ ChoiceCell cell2 = new ChoiceCell("cell 2", null, Test.GENERAL_ARTWORK);
+ HashSet<ChoiceCell> cellsToPreload = new HashSet<>();
+ cellsToPreload.add(cell1);
+ cellsToPreload.add(cell2);
- boolean test2 = preloadChoicesOperation.hasTextFieldOfName(TextFieldName.menuName);
- assertTrue(test2);
+ ImageField imageField = new ImageField();
+ imageField.setName(ImageFieldName.alertIcon);
+
+ TextField textField = new TextField();
+ textField.setName(TextFieldName.mainField1);
+
+ WindowCapability windowCapability = new WindowCapability();
+ windowCapability.setImageFields(Collections.singletonList(imageField));
+ windowCapability.setTextFields(Collections.singletonList(textField));
+
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
+ preloadChoicesOperationEmptyCapability = new PreloadChoicesOperation(internalInterface, fileManager, null, windowCapability, true, cellsToPreload, null);
}
- public void testHasImageFieldOfName(){
- boolean test = preloadChoicesOperation.hasImageFieldOfName(ImageFieldName.choiceImage);
- assertTrue(test);
- boolean test2 = preloadChoicesOperation.hasImageFieldOfName(ImageFieldName.appIcon);
- assertFalse(test2);
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
}
public void testArtworkNeedsUpload(){
@@ -116,4 +156,31 @@ public class PreloadChoicesOperationTests extends AndroidTestCase2 {
assertEquals(artworksToUpload.size(), 1);
}
+ /**
+ * Testing shouldSend method's with varying WindowCapability set.
+ */
+ public void testShouldSendText() {
+
+ setUpNullWindowCapability();
+ assertTrue(preloadChoicesOperationNullCapability.shouldSendChoicePrimaryImage());
+ assertTrue(preloadChoicesOperationNullCapability.shouldSendChoiceSecondaryImage());
+ assertTrue(preloadChoicesOperationNullCapability.shouldSendChoiceSecondaryText());
+ assertTrue(preloadChoicesOperationNullCapability.shouldSendChoiceTertiaryText());
+ assertTrue(preloadChoicesOperationNullCapability.shouldSendChoiceText());
+
+
+ assertTrue(preloadChoicesOperation.shouldSendChoicePrimaryImage());
+ assertTrue(preloadChoicesOperation.shouldSendChoiceSecondaryImage());
+ assertTrue(preloadChoicesOperation.shouldSendChoiceSecondaryText());
+ assertTrue(preloadChoicesOperation.shouldSendChoiceTertiaryText());
+ assertTrue(preloadChoicesOperation.shouldSendChoiceText());
+
+ setUpEmptyWindowCapability();
+ assertFalse(preloadChoicesOperationEmptyCapability.shouldSendChoicePrimaryImage());
+ assertFalse(preloadChoicesOperationEmptyCapability.shouldSendChoiceSecondaryImage());
+ assertFalse(preloadChoicesOperationEmptyCapability.shouldSendChoiceSecondaryText());
+ assertFalse(preloadChoicesOperationEmptyCapability.shouldSendChoiceTertiaryText());
+ assertFalse(preloadChoicesOperationEmptyCapability.shouldSendChoiceText());
+ }
+
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java
index a89a0771a..feca36cdf 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java
@@ -46,6 +46,7 @@ import com.smartdevicelink.proxy.rpc.OnCommand;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.SdlMsgVersion;
import com.smartdevicelink.proxy.rpc.SetGlobalProperties;
+import com.smartdevicelink.proxy.rpc.WindowCapability;
import com.smartdevicelink.proxy.rpc.enums.FileType;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.MenuLayout;
@@ -57,6 +58,7 @@ import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -495,6 +497,10 @@ public class MenuManagerTests extends AndroidTestCase2 {
menuManager.currentHMILevel = HMILevel.HMI_FULL;
menuManager.currentSystemContext = SystemContext.SYSCTXT_MAIN;
menuManager.sdlMsgVersion = new SdlMsgVersion(6,0);
+ menuManager.defaultMainWindowCapability = new WindowCapability();
+
+ List<MenuLayout> menuLayouts = Arrays.asList(MenuLayout.LIST, MenuLayout.TILES);
+ menuManager.defaultMainWindowCapability.setMenuLayoutsAvailable(menuLayouts);
MenuConfiguration menuConfigurationTest = new MenuConfiguration(MenuLayout.LIST, MenuLayout.LIST);
menuManager.setMenuConfiguration(menuConfigurationTest);
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java
index 34a452f06..1b7417363 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java
@@ -19,11 +19,15 @@ import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.ImageResolution;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.OnTouchEvent;
+import com.smartdevicelink.proxy.rpc.RegisterAppInterface;
+import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse;
import com.smartdevicelink.proxy.rpc.TouchCoord;
import com.smartdevicelink.proxy.rpc.TouchEvent;
+import com.smartdevicelink.proxy.rpc.VehicleType;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.enums.TouchType;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingState;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
import com.smartdevicelink.streaming.video.VideoStreamingParameters;
@@ -99,6 +103,12 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
ISdl internalInterface = mock(ISdl.class);
when(internalInterface.getProtocolVersion()).thenReturn(new Version(5,1,0));
+ RegisterAppInterfaceResponse mockRegisterAppInterfaceResponse = new RegisterAppInterfaceResponse();
+ VehicleType mockVehicleType = new VehicleType();
+ mockVehicleType.setMake("Ford");
+ mockRegisterAppInterfaceResponse.setVehicleType(mockVehicleType);
+ when(internalInterface.getRegisterAppInterfaceResponse()).thenReturn(mockRegisterAppInterfaceResponse);
+
Answer<Void> onAddServiceListener = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
@@ -126,6 +136,13 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
final ISdl internalInterface = mock(ISdl.class);
when(internalInterface.getProtocolVersion()).thenReturn((new Version(5,0,0)));
+
+ RegisterAppInterfaceResponse mockRegisterAppInterfaceResponse = new RegisterAppInterfaceResponse();
+ VehicleType mockVehicleType = new VehicleType();
+ mockVehicleType.setMake("Ford");
+ mockRegisterAppInterfaceResponse.setVehicleType(mockVehicleType);
+ when(internalInterface.getRegisterAppInterfaceResponse()).thenReturn(mockRegisterAppInterfaceResponse);
+
when(internalInterface.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)).thenReturn(true);
final VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
@@ -143,6 +160,12 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
public void testRemoteDisplayStream(){
ISdl internalInterface = mock(ISdl.class);
+ RegisterAppInterfaceResponse mockRegisterAppInterfaceResponse = new RegisterAppInterfaceResponse();
+ VehicleType mockVehicleType = new VehicleType();
+ mockVehicleType.setMake("Ford");
+ mockRegisterAppInterfaceResponse.setVehicleType(mockVehicleType);
+ when(internalInterface.getRegisterAppInterfaceResponse()).thenReturn(mockRegisterAppInterfaceResponse);
+
final Set<Object> listenerSet = new HashSet<>();
when(internalInterface.getProtocolVersion()).thenReturn(new Version(5,0,0));
@@ -252,6 +275,13 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
public void testConvertTouchEvent() {
ISdl internalInterface = mock(ISdl.class);
+
+ RegisterAppInterfaceResponse mockRegisterAppInterfaceResponse = new RegisterAppInterfaceResponse();
+ VehicleType mockVehicleType = new VehicleType();
+ mockVehicleType.setMake("Ford");
+ mockRegisterAppInterfaceResponse.setVehicleType(mockVehicleType);
+ when(internalInterface.getRegisterAppInterfaceResponse()).thenReturn(mockRegisterAppInterfaceResponse);
+
VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
List<MotionEvent> motionEventList;
long e1TS = 1558124390L, e2TS = 1558125390L, e3TS = 1558126390L;
@@ -467,6 +497,12 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
private void assertMotionEventWithScale(int width, int height, float scale) {
ISdl internalInterface = mock(ISdl.class);
+ RegisterAppInterfaceResponse mockRegisterAppInterfaceResponse = new RegisterAppInterfaceResponse();
+ VehicleType mockVehicleType = new VehicleType();
+ mockVehicleType.setMake("Ford");
+ mockRegisterAppInterfaceResponse.setVehicleType(mockVehicleType);
+ when(internalInterface.getRegisterAppInterfaceResponse()).thenReturn(mockRegisterAppInterfaceResponse);
+
// Preferred Resolution capability
ImageResolution resolution = new ImageResolution(width, height);
@@ -496,4 +532,39 @@ public class VideoStreamManagerTests extends AndroidTestCase2 {
assertEquals(Math.round(e1x / scale), Math.round(motionEvent.getX(0)));
assertEquals(Math.round(e1y / scale), Math.round(motionEvent.getY(0)));
}
+
+ public void testIsHMIStateVideoStreamCapable() {
+ VideoStreamManager videoStreamManager = new VideoStreamManager(mock(ISdl.class));
+
+ // Case 1 (VideoStreamingState = STREAMABLE)
+ assertTrue(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_FULL, VideoStreamingState.STREAMABLE)));
+ assertTrue(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_LIMITED, VideoStreamingState.STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_BACKGROUND, VideoStreamingState.STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_NONE, VideoStreamingState.STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(null, VideoStreamingState.STREAMABLE)));
+
+ // Case 2 (VideoStreamingState = NOT_STREAMABLE)
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_FULL, VideoStreamingState.NOT_STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_LIMITED, VideoStreamingState.NOT_STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_BACKGROUND, VideoStreamingState.NOT_STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_NONE, VideoStreamingState.NOT_STREAMABLE)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(null, VideoStreamingState.NOT_STREAMABLE)));
+
+ // Case 3 (VideoStreamingState = NULL)
+ assertTrue(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_FULL, null)));
+ assertTrue(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_LIMITED, null)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_BACKGROUND, null)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(HMILevel.HMI_NONE, null)));
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(createOnHMIStatus(null, null)));
+
+ // Case 4 (onHMIStatus = NULL)
+ assertFalse(videoStreamManager.isHMIStateVideoStreamCapable(null));
+ }
+
+ private OnHMIStatus createOnHMIStatus(HMILevel hmiLevel, VideoStreamingState videoStreamingState) {
+ OnHMIStatus onHMIStatus = new OnHMIStatus();
+ onHMIStatus.setHmiLevel(hmiLevel);
+ onHMIStatus.setVideoStreamingState(videoStreamingState);
+ return onHMIStatus;
+ }
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
index 68465b2d4..602e638ae 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
@@ -1,6 +1,7 @@
package com.smartdevicelink.test;
import android.graphics.Color;
+import android.net.Uri;
import android.util.Log;
import com.smartdevicelink.R;
@@ -264,6 +265,7 @@ public class Test {
public static final ImageField GENERAL_IMAGEFIELD = new ImageField();
public static final DeviceInfo GENERAL_DEVICEINFO = new DeviceInfo();
public static final AppInfo GENERAL_APPINFO = new AppInfo();
+ public static final Uri GENERAL_URI = Uri.parse("http://www.google.com");;
public static final LayoutMode GENERAL_LAYOUTMODE = LayoutMode.LIST_ONLY;
public static final MenuParams GENERAL_MENUPARAMS = new MenuParams();
public static final SoftButton GENERAL_SOFTBUTTON = new SoftButton();
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
index 0d1fa04bf..87bed3d1b 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
@@ -19,8 +19,10 @@ import com.smartdevicelink.proxy.rpc.AudioPassThruCapabilities;
import com.smartdevicelink.proxy.rpc.ButtonCapabilities;
import com.smartdevicelink.proxy.rpc.DisplayCapabilities;
import com.smartdevicelink.proxy.rpc.DisplayCapability;
+import com.smartdevicelink.proxy.rpc.GetSystemCapability;
import com.smartdevicelink.proxy.rpc.GetSystemCapabilityResponse;
import com.smartdevicelink.proxy.rpc.HMICapabilities;
+import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.OnSystemCapabilityUpdated;
import com.smartdevicelink.proxy.rpc.PhoneCapability;
import com.smartdevicelink.proxy.rpc.PresetBankCapabilities;
@@ -33,7 +35,9 @@ import com.smartdevicelink.proxy.rpc.VideoStreamingCapability;
import com.smartdevicelink.proxy.rpc.WindowCapability;
import com.smartdevicelink.proxy.rpc.WindowTypeCapabilities;
import com.smartdevicelink.proxy.rpc.enums.AppServiceType;
+import com.smartdevicelink.proxy.rpc.enums.AudioStreamingState;
import com.smartdevicelink.proxy.rpc.enums.DisplayType;
+import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities;
import com.smartdevicelink.proxy.rpc.enums.ImageType;
import com.smartdevicelink.proxy.rpc.enums.MediaClockFormat;
@@ -43,6 +47,7 @@ import com.smartdevicelink.proxy.rpc.enums.Result;
import com.smartdevicelink.proxy.rpc.enums.ServiceUpdateReason;
import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
+import com.smartdevicelink.proxy.rpc.enums.SystemContext;
import com.smartdevicelink.proxy.rpc.enums.WindowType;
import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener;
@@ -57,18 +62,38 @@ import com.smartdevicelink.test.utl.AppServiceFactory;
import com.smartdevicelink.util.CorrelationIdGenerator;
import com.smartdevicelink.util.Version;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
public class SystemCapabilityManagerTests extends AndroidTestCase2 {
public static final String TAG = "SystemCapabilityManagerTests";
public static SystemCapabilityManager systemCapabilityManager;
+ private SystemCapability systemCapability;
+ private VideoStreamingCapability videoStreamingCapability;
@Override
protected void setUp() throws Exception{
super.setUp();
+
+ systemCapability = new SystemCapability(SystemCapabilityType.VIDEO_STREAMING);
+ videoStreamingCapability = new VideoStreamingCapability();
+ videoStreamingCapability.setMaxBitrate(Test.GENERAL_INT);
+ videoStreamingCapability.setPreferredResolution(Test.GENERAL_IMAGERESOLUTION);
+ videoStreamingCapability.setSupportedFormats(Test.GENERAL_VIDEOSTREAMINGFORMAT_LIST);
+ systemCapability.setCapabilityForType(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
}
@Override
@@ -187,11 +212,19 @@ public class SystemCapabilityManagerTests extends AndroidTestCase2 {
systemCapabilityManager = new SystemCapabilityManager(new InternalSDLInterface() {
@Override
- public void sendRPCRequest(RPCRequest message) {
+ public void sendRPC(RPCMessage message) {
GetSystemCapabilityResponse response = new GetSystemCapabilityResponse();
response.setSystemCapability(referenceCapability);
response.setSuccess(true);
- message.getOnRPCResponseListener().onResponse(CorrelationIdGenerator.generateId(), response);
+ if (message instanceof RPCRequest) {
+ RPCRequest request = (RPCRequest) message;
+ request.getOnRPCResponseListener().onResponse(CorrelationIdGenerator.generateId(), response);
+ }
+ }
+
+ @Override
+ public void addOnRPCListener(FunctionID messageId, OnRPCListener listener) {
+ listener.onReceived(new OnHMIStatus(HMILevel.HMI_FULL, AudioStreamingState.NOT_AUDIBLE, SystemContext.SYSCTXT_MAIN));
}
});
@@ -211,13 +244,429 @@ public class SystemCapabilityManagerTests extends AndroidTestCase2 {
});
}
+ private Answer<Void> createOnHMIStatusAnswer(final HMILevel hmiLevel){
+ Answer<Void> onHMIStatusAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ OnRPCListener onHMIStatusListener = (OnRPCListener) args[1];
+ OnHMIStatus onHMIStatusFakeNotification = new OnHMIStatus();
+ onHMIStatusFakeNotification.setHmiLevel(hmiLevel);
+ onHMIStatusListener.onReceived(onHMIStatusFakeNotification);
+ return null;
+ }
+ };
+ return onHMIStatusAnswer;
+ }
+
+ private Answer<Void> createOnSendGetSystemCapabilityAnswer (final boolean success, final Boolean subscribe) {
+ Answer<Void> onSendGetSystemCapabilityAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ GetSystemCapability getSystemCapability = (GetSystemCapability) args[0];
+ if (subscribe != null) {
+ assertEquals(subscribe, getSystemCapability.getSubscribe());
+ }
+ GetSystemCapabilityResponse response;
+ if (success) {
+ response = new GetSystemCapabilityResponse(Result.SUCCESS, true);
+ } else {
+ response = new GetSystemCapabilityResponse(Result.REJECTED, false);
+ }
+ response.setSystemCapability(systemCapability);
+ getSystemCapability.getOnRPCResponseListener().onResponse(CorrelationIdGenerator.generateId(), response);
+ return null;
+ }
+ };
+ return onSendGetSystemCapabilityAnswer;
+ }
+
+ public void testGetCapability() {
+ ISdl internalInterface;
+ SystemCapabilityManager scm;
+ OnSystemCapabilityListener onSystemCapabilityListener;
+ VideoStreamingCapability retrievedCapability;
+
+
+ // Test case 1 (capability not cached, listener not null, forceUpdate false)
+ internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ scm = new SystemCapabilityManager(internalInterface);
+ onSystemCapabilityListener = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, null);
+ retrievedCapability = (VideoStreamingCapability) scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener, false);
+ assertNull(retrievedCapability);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Test case 2 (capability cached, listener not null, forceUpdate true)
+ internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ scm = new SystemCapabilityManager(internalInterface);
+ onSystemCapabilityListener = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+ retrievedCapability = (VideoStreamingCapability) scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener, true);
+ assertTrue(Test.TRUE, Validator.validateVideoStreamingCapability((VideoStreamingCapability) systemCapability.getCapabilityForType(SystemCapabilityType.VIDEO_STREAMING), retrievedCapability));
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Test case 3 (capability cached, listener null, forceUpdate true)
+ internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ scm = new SystemCapabilityManager(internalInterface);
+ onSystemCapabilityListener = null;
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+ retrievedCapability = (VideoStreamingCapability) scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener, true);
+ assertTrue(Test.TRUE, Validator.validateVideoStreamingCapability((VideoStreamingCapability) systemCapability.getCapabilityForType(SystemCapabilityType.VIDEO_STREAMING), retrievedCapability));
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+
+
+ // Test case 4 (capability cached, listener null, forceUpdate false)
+ internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ scm = new SystemCapabilityManager(internalInterface);
+ onSystemCapabilityListener = null;
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+ retrievedCapability = (VideoStreamingCapability) scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener, false);
+ assertTrue(Test.TRUE, Validator.validateVideoStreamingCapability((VideoStreamingCapability) systemCapability.getCapabilityForType(SystemCapabilityType.VIDEO_STREAMING), retrievedCapability));
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ }
+
+ public void testGetCapabilityHmiNone() {
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_NONE)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ OnSystemCapabilityListener onSystemCapabilityListener = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, null);
+ VideoStreamingCapability retrievedCapability = (VideoStreamingCapability) scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener, false);
+ assertNull(retrievedCapability);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener, times(0)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener, times(1)).onError(any(String.class));
+ }
+
+ public void testAddOnSystemCapabilityListenerWithSubscriptionsSupportedAndCapabilityCached() {
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(6, 0); // This version supports capability subscriptions
+ sdlMsgVersion.setPatchVersion(0);
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(sdlMsgVersion);
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+
+
+ // Add listener1
+ // When the first listener is added, GetSystemCapability request should go out with subscribe=true
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, true)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener2
+ OnSystemCapabilityListener onSystemCapabilityListener2 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+ verify(onSystemCapabilityListener2, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener3
+ OnSystemCapabilityListener onSystemCapabilityListener3 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(onSystemCapabilityListener3, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener1
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+
+
+ // Remove listener2
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+
+
+ // Remove listener3
+ // When the last listener is removed, GetSystemCapability request should go out with subscribe=false
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(internalInterface, times(2)).sendRPC(any(GetSystemCapability.class));
+ }
+
+ public void testAddOnSystemCapabilityListenerWithSubscriptionsSupportedAndCapabilityNotCached() {
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(6, 0); // This version supports capability subscriptions
+ sdlMsgVersion.setPatchVersion(0);
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(sdlMsgVersion);
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, null);
+
+
+ // Add listener1
+ // When the first listener is added, GetSystemCapability request should go out with subscribe=true
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, true)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener2
+ OnSystemCapabilityListener onSystemCapabilityListener2 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+ verify(onSystemCapabilityListener2, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener3
+ OnSystemCapabilityListener onSystemCapabilityListener3 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(onSystemCapabilityListener3, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener1
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+
+
+ // Remove listener2
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+
+
+ // Remove listener3
+ // When the last listener is removed, GetSystemCapability request should go out with subscribe=false
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(internalInterface, times(2)).sendRPC(any(GetSystemCapability.class));
+ }
+
+ public void testAddOnSystemCapabilityListenerWithSubscriptionsNotSupportedAndCapabilityCached() {
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(5, 0); // This version doesn't support capability subscriptions
+ sdlMsgVersion.setPatchVersion(0);
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(sdlMsgVersion);
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+
+
+ // Add listener1
+ // When the first listener is added, GetSystemCapability request should not go out because subscription is not supported and the capability is cached
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, true)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener2
+ OnSystemCapabilityListener onSystemCapabilityListener2 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+ verify(onSystemCapabilityListener2, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener3
+ OnSystemCapabilityListener onSystemCapabilityListener3 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(onSystemCapabilityListener3, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener1
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+
+
+ // Remove listener2
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+
+
+ // Remove listener3
+ // When the last listener is removed, GetSystemCapability request should not go out because subscription is not supported
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ }
+
+ public void testAddOnSystemCapabilityListenerWithSubscriptionsNotSupportedAndCapabilityNotCached() {
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(5, 0); // This version doesn't support capability subscriptions
+ sdlMsgVersion.setPatchVersion(0);
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(sdlMsgVersion);
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, null);
+
+
+ // Add listener1
+ // When the first listener is added, GetSystemCapability request should out because because capability is not cached
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener2
+ OnSystemCapabilityListener onSystemCapabilityListener2 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+ verify(onSystemCapabilityListener2, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener3
+ OnSystemCapabilityListener onSystemCapabilityListener3 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(onSystemCapabilityListener3, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener1
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+
+
+ // Remove listener2
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+
+
+ // Remove listener3
+ // When the last listener is removed, GetSystemCapability request should not go out because subscription is not supported
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ }
+
+ public void testAddOnSystemCapabilityListenerThenGetCapabilityWhenSubscriptionsAreNotSupported() {
+ SdlMsgVersion sdlMsgVersion = new SdlMsgVersion(5, 0); // This version doesn't support capability subscriptions
+ sdlMsgVersion.setPatchVersion(0);
+ ISdl internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(sdlMsgVersion);
+ SystemCapabilityManager scm = new SystemCapabilityManager(internalInterface);
+ scm.setCapability(SystemCapabilityType.VIDEO_STREAMING, videoStreamingCapability);
+
+
+ // Add listener1
+ // When the first listener is added, GetSystemCapability request should go out with subscribe=false
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, false)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Get Capability (should notify listener1 again)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(1)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(2)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener2
+ OnSystemCapabilityListener onSystemCapabilityListener2 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+ verify(onSystemCapabilityListener2, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Get Capability (should notify listener1 & listener2 again)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(2)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(3)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener2, times(2)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Add listener3
+ OnSystemCapabilityListener onSystemCapabilityListener3 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(onSystemCapabilityListener3, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Get Capability (should notify listener1 & listener2 & listener3 again)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(3)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener2, times(3)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener3, times(2)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener1
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener1);
+
+
+ // Get Capability (should notify listener2 & listener3 again)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(4)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener2, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener3, times(3)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener2
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener2);
+
+
+ // Get Capability (should notify listener3 again)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(5)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener2, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener3, times(4)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Remove listener3
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.VIDEO_STREAMING, onSystemCapabilityListener3);
+ verify(internalInterface, times(5)).sendRPC(any(GetSystemCapability.class));
+
+
+ // Get Capability (should not notify any listener again because they are all removed)
+ scm.getCapability(SystemCapabilityType.VIDEO_STREAMING, null, true);
+ verify(internalInterface, times(6)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener2, times(4)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener3, times(4)).onCapabilityRetrieved(any(Object.class));
+ }
+
+ public void testGetAndAddListenerForDisplaysCapability() {
+ ISdl internalInterface;
+ SystemCapabilityManager scm;
+ OnSystemCapabilityListener onSystemCapabilityListener;
+ DisplayCapabilities retrievedCapability;
+
+
+ // Test case 1 (capability cached, listener not null, forceUpdate true)
+ internalInterface = mock(ISdl.class);
+ doAnswer(createOnHMIStatusAnswer(HMILevel.HMI_FULL)).when(internalInterface).addOnRPCListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCListener.class));
+ scm = new SystemCapabilityManager(internalInterface);
+ onSystemCapabilityListener = mock(OnSystemCapabilityListener.class);
+ doAnswer(createOnSendGetSystemCapabilityAnswer(true, null)).when(internalInterface).sendRPC(any(GetSystemCapability.class));
+ scm.setCapability(SystemCapabilityType.DISPLAYS, new DisplayCapabilities());
+ retrievedCapability = (DisplayCapabilities) scm.getCapability(SystemCapabilityType.DISPLAYS, onSystemCapabilityListener, true);
+ assertNotNull(retrievedCapability);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener, times(1)).onCapabilityRetrieved(any(Object.class));
+ verify(onSystemCapabilityListener, times(0)).onError(any(String.class));
+
+
+ // Test case 2 (Add listener)
+ // When the first DISPLAYS listener is added, GetSystemCapability request should not go out
+ OnSystemCapabilityListener onSystemCapabilityListener1 = mock(OnSystemCapabilityListener.class);
+ scm.addOnSystemCapabilityListener(SystemCapabilityType.DISPLAYS, onSystemCapabilityListener1);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ verify(onSystemCapabilityListener1, times(1)).onCapabilityRetrieved(any(Object.class));
+
+
+ // Test case 3 (Remove listener)
+ // When the last DISPLAYS listener is removed, GetSystemCapability request should not go out
+ scm.removeOnSystemCapabilityListener(SystemCapabilityType.DISPLAYS, onSystemCapabilityListener1);
+ verify(internalInterface, times(0)).sendRPC(any(GetSystemCapability.class));
+ }
+
public void testListConversion(){
SystemCapabilityManager systemCapabilityManager = createSampleManager();
Object capability = systemCapabilityManager.getCapability(SystemCapabilityType.SOFTBUTTON);
assertNotNull(capability);
List<SoftButtonCapabilities> list = SystemCapabilityManager.convertToList(capability, SoftButtonCapabilities.class);
assertNotNull(list);
-
}
public void testFalsePositive(){
@@ -282,7 +731,6 @@ public class SystemCapabilityManagerTests extends AndroidTestCase2 {
}
public void testOnSystemCapabilityUpdated(){
-
InternalSDLInterface iSDL = new InternalSDLInterface();
String baseName = "NavTest", baseID = "37F98053AE";
AppServiceCapability capability1 = AppServiceFactory.createAppServiceCapability(AppServiceType.NAVIGATION, baseName, null, true, null);
@@ -547,10 +995,21 @@ public class SystemCapabilityManagerTests extends AndroidTestCase2 {
public Object getCapability(SystemCapabilityType systemCapabilityType){return null;}
@Override
- public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { }
+ public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) {
+ }
+
+ @Override
+ public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() {
+ return null;
+ }
+
+ @Override
+ public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) {
+ return null;
+ }
@Override
- public SdlMsgVersion getSdlMsgVersion(){
+ public SdlMsgVersion getSdlMsgVersion() {
return null;
}
@@ -597,6 +1056,4 @@ public class SystemCapabilityManagerTests extends AndroidTestCase2 {
@Override
public void startRPCEncryption() {}
}
-
-
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppInterfaceUnregisteredReasonTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppInterfaceUnregisteredReasonTests.java
index cdc7375df..cc59924d4 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppInterfaceUnregisteredReasonTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppInterfaceUnregisteredReasonTests.java
@@ -42,6 +42,8 @@ public class AppInterfaceUnregisteredReasonTests extends TestCase {
AppInterfaceUnregisteredReason enumAppAuthorized = AppInterfaceUnregisteredReason.valueForString(example);
example = "PROTOCOL_VIOLATION";
AppInterfaceUnregisteredReason enumProtocolViolation = AppInterfaceUnregisteredReason.valueForString(example);
+ example = "UNSUPPORTED_HMI_RESOURCE";
+ AppInterfaceUnregisteredReason enumUnsupportedHMIResource = AppInterfaceUnregisteredReason.valueForString(example);
assertNotNull("USER_EXIT returned null", enumUserExit);
assertNotNull("IGNITION_OFF returned null", enumIgnitionOff);
@@ -55,6 +57,7 @@ public class AppInterfaceUnregisteredReasonTests extends TestCase {
assertNotNull("FACTORY_DEFAULTS returned null", enumFactoryDefaults);
assertNotNull("APP_UNAUTHORIZED returned null", enumAppAuthorized);
assertNotNull("PROTOCOL_VIOLATION returned null", enumProtocolViolation);
+ assertNotNull("UNSUPPORTED_HMI_RESOURCE returned null", enumUnsupportedHMIResource);
}
/**
@@ -104,6 +107,7 @@ public class AppInterfaceUnregisteredReasonTests extends TestCase {
enumTestList.add(AppInterfaceUnregisteredReason.FACTORY_DEFAULTS);
enumTestList.add(AppInterfaceUnregisteredReason.APP_UNAUTHORIZED);
enumTestList.add(AppInterfaceUnregisteredReason.PROTOCOL_VIOLATION);
+ enumTestList.add(AppInterfaceUnregisteredReason.UNSUPPORTED_HMI_RESOURCE);
assertTrue("Enum value list does not match enum class list",
enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MaintenanceModeStatusTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MaintenanceModeStatusTests.java
new file mode 100644
index 000000000..9254cd2b2
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MaintenanceModeStatusTests.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.MaintenanceModeStatus;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.proxy.rpc.enums.MaintenanceModeStatus}
+ */
+public class MaintenanceModeStatusTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "NORMAL";
+ MaintenanceModeStatus enumNormal = MaintenanceModeStatus.valueForString(example);
+ example = "NEAR";
+ MaintenanceModeStatus enumNear = MaintenanceModeStatus.valueForString(example);
+ example = "ACTIVE";
+ MaintenanceModeStatus enumActive = MaintenanceModeStatus.valueForString(example);
+ example = "FEATURE_NOT_PRESENT";
+ MaintenanceModeStatus enumFeatureNotPResent = MaintenanceModeStatus.valueForString(example);
+
+ assertNotNull("NORMAL returned null", enumNormal);
+ assertNotNull("NEAR returned null", enumNear);
+ assertNotNull("ACTIVE returned null", enumActive);
+ assertNotNull("FEATURE_NOT_PRESENT returned null", enumFeatureNotPResent);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "normAL";
+ try {
+ MaintenanceModeStatus temp = MaintenanceModeStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ MaintenanceModeStatus temp = MaintenanceModeStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of MaintenanceModeStatus.
+ */
+ public void testListEnum() {
+ List<MaintenanceModeStatus> enumValueList = Arrays.asList(MaintenanceModeStatus.values());
+
+ List<MaintenanceModeStatus> enumTestList = new ArrayList<>();
+ enumTestList.add(MaintenanceModeStatus.NORMAL);
+ enumTestList.add(MaintenanceModeStatus.NEAR);
+ enumTestList.add(MaintenanceModeStatus.ACTIVE);
+ enumTestList.add(MaintenanceModeStatus.FEATURE_NOT_PRESENT);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MessageTypeTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MessageTypeTests.java
new file mode 100644
index 000000000..354948cdf
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/MessageTypeTests.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2020 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.MessageType;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.proxy.rpc.enums.MessageType}
+ */
+public class MessageTypeTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums() {
+ int example = 0;
+ MessageType enumRequest = MessageType.valueForInt(example);
+ example = 1;
+ MessageType enumResponse = MessageType.valueForInt(example);
+ example = 2;
+ MessageType enumNotification = MessageType.valueForInt(example);
+
+ assertNotNull("REQUEST returned null", enumRequest);
+ assertNotNull("RESPONSE returned null", enumResponse);
+ assertNotNull("NOTIFICATION returned null", enumNotification);
+
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum() {
+ int example = 3;
+ try {
+ MessageType temp = MessageType.valueForInt(example);
+ assertNull("Result of valueForString should be null.", temp);
+ } catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+
+ /**
+ * Verifies the possible enum values of MessageType.
+ */
+ public void testListEnum() {
+ List<MessageType> enumValueList = Arrays.asList(MessageType.values());
+
+ List<MessageType> enumTestList = new ArrayList<>();
+ enumTestList.add(MessageType.REQUEST);
+ enumTestList.add(MessageType.RESPONSE);
+ enumTestList.add(MessageType.NOTIFICATION);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/PermissionStatusTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/PermissionStatusTests.java
new file mode 100644
index 000000000..2a11db43f
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/PermissionStatusTests.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.PermissionStatus;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.proxy.rpc.enums.PermissionStatus}
+ */
+public class PermissionStatusTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "ALLOWED";
+ PermissionStatus enumAllowed = PermissionStatus.valueForString(example);
+ example = "DISALLOWED";
+ PermissionStatus enumDisallowed = PermissionStatus.valueForString(example);
+ example = "USER_DISALLOWED";
+ PermissionStatus enumUserDisallowed = PermissionStatus.valueForString(example);
+ example = "USER_CONSENT_PENDING";
+ PermissionStatus enumUserConsentPending = PermissionStatus.valueForString(example);
+
+ assertNotNull("ALLOWED returned null", enumAllowed);
+ assertNotNull("DISALLOWED returned null", enumDisallowed);
+ assertNotNull("USER_DISALLOWED returned null", enumUserDisallowed);
+ assertNotNull("USER_CONSENT_PENDING returned null", enumUserConsentPending);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "DISALLOwed";
+ try {
+ PermissionStatus temp = PermissionStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ PermissionStatus temp = PermissionStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of PermissionStatus.
+ */
+ public void testListEnum() {
+ List<PermissionStatus> enumValueList = Arrays.asList(PermissionStatus.values());
+
+ List<PermissionStatus> enumTestList = new ArrayList<>();
+ enumTestList.add(PermissionStatus.ALLOWED);
+ enumTestList.add(PermissionStatus.DISALLOWED);
+ enumTestList.add(PermissionStatus.USER_DISALLOWED);
+ enumTestList.add(PermissionStatus.USER_CONSENT_PENDING);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
index f3b374b4c..8bfec0490 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
@@ -28,6 +28,8 @@ public class ResultTests extends TestCase {
Result enumOutOfMemory = Result.valueForString(example);
example = "TOO_MANY_PENDING_REQUESTS";
Result enumTooManyPendingRequests = Result.valueForString(example);
+ example = "CHAR_LIMIT_EXCEEDED";
+ Result enumCharLimitExceeded = Result.valueForString(example);
example = "INVALID_ID";
Result enumInvalidId = Result.valueForString(example);
example = "DUPLICATE_NAME";
@@ -96,6 +98,7 @@ public class ResultTests extends TestCase {
assertNotNull("UNSUPPORTED_REQUEST returned null", enumUnsupportedRequest);
assertNotNull("OUT_OF_MEMORY returned null", enumOutOfMemory);
assertNotNull("TOO_MANY_PENDING_REQUESTS returned null", enumTooManyPendingRequests);
+ assertNotNull("CHAR_LIMIT_EXCEEDED returned null", enumCharLimitExceeded);
assertNotNull("INVALID_ID returned null", enumInvalidId);
assertNotNull("DUPLICATE_NAME returned null", enumDuplicateName);
assertNotNull("TOO_MANY_APPLICATIONS returned null", enumTooManyApplications);
@@ -169,6 +172,7 @@ public class ResultTests extends TestCase {
enumTestList.add(Result.UNSUPPORTED_REQUEST);
enumTestList.add(Result.OUT_OF_MEMORY);
enumTestList.add(Result.TOO_MANY_PENDING_REQUESTS);
+ enumTestList.add(Result.CHAR_LIMIT_EXCEEDED);
enumTestList.add(Result.INVALID_ID);
enumTestList.add(Result.DUPLICATE_NAME);
enumTestList.add(Result.TOO_MANY_APPLICATIONS);
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TimerModeTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TimerModeTests.java
new file mode 100644
index 000000000..892159a0d
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TimerModeTests.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2020 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.TimerMode;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.proxy.rpc.enums.TimerMode}
+ */
+public class TimerModeTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "UP";
+ TimerMode enumUp = TimerMode.valueForString(example);
+ example = "DOWN";
+ TimerMode enumDown = TimerMode.valueForString(example);
+ example = "NONE";
+ TimerMode enumNone = TimerMode.valueForString(example);
+
+ assertNotNull("UP returned null", enumUp);
+ assertNotNull("DOWN returned null", enumDown);
+ assertNotNull("NONE returned null", enumNone);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "NonE";
+ try {
+ TimerMode temp = TimerMode.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ TimerMode temp = TimerMode.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of TimerMode.
+ */
+ public void testListEnum() {
+ List<TimerMode> enumValueList = Arrays.asList(TimerMode.values());
+
+ List<TimerMode> enumTestList = new ArrayList<>();
+ enumTestList.add(TimerMode.UP);
+ enumTestList.add(TimerMode.DOWN);
+ enumTestList.add(TimerMode.NONE);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VehicleDataActiveStatusTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VehicleDataActiveStatusTests.java
new file mode 100644
index 000000000..b6ba15a7a
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VehicleDataActiveStatusTests.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020 Livio, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Livio Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.VehicleDataActiveStatus;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.proxy.rpc.enums.VehicleDataActiveStatus}
+ */
+public class VehicleDataActiveStatusTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "INACTIVE_NOT_CONFIRMED";
+ VehicleDataActiveStatus enumInactiveNotConfirmed = VehicleDataActiveStatus.valueForString(example);
+ example = "INACTIVE_CONFIRMED";
+ VehicleDataActiveStatus enumInactiveConfirmed = VehicleDataActiveStatus.valueForString(example);
+ example = "ACTIVE_NOT_CONFIRMED";
+ VehicleDataActiveStatus enumActiveNotConfirmed = VehicleDataActiveStatus.valueForString(example);
+ example = "ACTIVE_CONFIRMED";
+ VehicleDataActiveStatus enumActiveConfirmed = VehicleDataActiveStatus.valueForString(example);
+ example = "FAULT";
+ VehicleDataActiveStatus enumFault = VehicleDataActiveStatus.valueForString(example);
+
+ assertNotNull("INACTIVE_NOT_CONFIRMED returned null", enumInactiveNotConfirmed);
+ assertNotNull("INACTIVE_CONFIRMED returned null", enumInactiveConfirmed);
+ assertNotNull("ACTIVE_NOT_CONFIRMED returned null", enumActiveNotConfirmed);
+ assertNotNull("ACTIVE_CONFIRMED returned null", enumActiveConfirmed);
+ assertNotNull("FAULT returned null", enumFault);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "FauLt";
+ try {
+ VehicleDataActiveStatus temp = VehicleDataActiveStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ VehicleDataActiveStatus temp = VehicleDataActiveStatus.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of VehicleDataActiveStatus.
+ */
+ public void testListEnum() {
+ List<VehicleDataActiveStatus> enumValueList = Arrays.asList(VehicleDataActiveStatus.values());
+
+ List<VehicleDataActiveStatus> enumTestList = new ArrayList<>();
+ enumTestList.add(VehicleDataActiveStatus.INACTIVE_NOT_CONFIRMED);
+ enumTestList.add(VehicleDataActiveStatus.INACTIVE_CONFIRMED);
+ enumTestList.add(VehicleDataActiveStatus.ACTIVE_NOT_CONFIRMED);
+ enumTestList.add(VehicleDataActiveStatus.ACTIVE_CONFIRMED);
+ enumTestList.add(VehicleDataActiveStatus.FAULT);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/video/VideoStreamingParametersTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/video/VideoStreamingParametersTest.java
index a81f69eb3..b894eca12 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/video/VideoStreamingParametersTest.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/video/VideoStreamingParametersTest.java
@@ -81,6 +81,66 @@ public class VideoStreamingParametersTest extends AndroidTestCase2 {
assertEquals(380, height);
}
+ public void testUpdateScale_1_0_Ford_Resolution_800_354() {
+ preferredResolution = new ImageResolution(800, 354);
+
+ capability.setScale(1.0);
+ capability.setPreferredResolution(preferredResolution);
+
+ params.update(capability, "Ford");
+
+ int width = params.getResolution().getResolutionWidth();
+ int height = params.getResolution().getResolutionHeight();
+
+ assertEquals(800, width);
+ assertEquals(354, height);
+ }
+
+ public void testUpdateScale_1_3_Lincoln_Resolution_600_900() {
+ preferredResolution = new ImageResolution(600, 900);
+
+ capability.setScale(1.0);
+ capability.setPreferredResolution(preferredResolution);
+
+ params.update(capability, "Lincoln");
+
+ int width = params.getResolution().getResolutionWidth();
+ int height = params.getResolution().getResolutionHeight();
+
+ assertEquals(450, width);
+ assertEquals(676, height);
+ }
+
+ public void testUpdateScale_1_3_Ford_Resolution_900_600() {
+ preferredResolution = new ImageResolution(900, 600);
+
+ capability.setScale(1.0);
+ capability.setPreferredResolution(preferredResolution);
+
+ params.update(capability, "Ford");
+
+ int width = params.getResolution().getResolutionWidth();
+ int height = params.getResolution().getResolutionHeight();
+
+ assertEquals(676, width);
+ assertEquals(450, height);
+ }
+
+ public void testUpdateScale_1_0_Toyota_Resolution_900_600() {
+ preferredResolution = new ImageResolution(900, 600);
+
+ capability.setScale(1.0);
+ capability.setPreferredResolution(preferredResolution);
+
+ params.update(capability, "Toyota");
+
+ int width = params.getResolution().getResolutionWidth();
+ int height = params.getResolution().getResolutionHeight();
+
+ assertEquals(900, width);
+ assertEquals(600, height);
+ }
+
public void testUpdateCapabilityFormat(){
VideoStreamingCapability capability = new VideoStreamingCapability();
capability.setMaxBitrate(10000);
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/RSVTestCase.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/RSVTestCase.java
index a6bc846fe..538d5fed4 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/RSVTestCase.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/RSVTestCase.java
@@ -4,6 +4,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.ConditionVariable;
import android.util.Log;
import com.smartdevicelink.AndroidTestCase2;
@@ -28,6 +29,7 @@ public class RSVTestCase extends AndroidTestCase2 {
private static final long REFRESH_TRUSTED_APP_LIST_TIME_MONTH = REFRESH_TRUSTED_APP_LIST_TIME_DAY * 30; // A ~month in ms
private static final String TEST = "{\"response\": {\"com.livio.sdl\" : { \"versionBlacklist\":[] }, \"com.lexus.tcapp\" : { \"versionBlacklist\":[] }, \"com.toyota.tcapp\" : { \"versionBlacklist\": [] } , \"com.sdl.router\":{\"versionBlacklist\": [] },\"com.ford.fordpass\" : { \"versionBlacklist\":[] } }}";
RouterServiceValidator rsvp;
+ private static final String APP_ID = "com.smartdevicelink.test.RSVTestCase";
/**
* Set this boolean if you want to test the actual validation of router service
*/
@@ -427,5 +429,36 @@ public class RSVTestCase extends AndroidTestCase2 {
assertTrue(rsvpPass.validate());
}
-
+ /**
+ * Unit test for validateAsync.
+ */
+ public void testValidateAsync() {
+ final MultiplexTransportConfig config = new MultiplexTransportConfig(mContext, APP_ID, MultiplexTransportConfig.FLAG_MULTI_SECURITY_HIGH);
+ final RouterServiceValidator validator = new RouterServiceValidator(config);
+ final ConditionVariable cond = new ConditionVariable();
+ validator.validateAsync(new RouterServiceValidator.ValidationStatusCallback() {
+ @Override
+ public void onFinishedValidation(boolean valid, ComponentName name) {
+ Log.d(TAG, "onFinishedValidation: valid=" + valid + "; componentName=" + name);
+ assertFalse(valid); // expected valid = false for this (bogus) APP_ID..
+ cond.open();
+ }
+ });
+ cond.block();
+
+ // next, test for FLAG_MULTI_SECURITY_OFF
+ final MultiplexTransportConfig config2 = new MultiplexTransportConfig(mContext, APP_ID, MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF);
+ final RouterServiceValidator validator2 = new RouterServiceValidator(config2);
+ cond.close();
+ validator2.validateAsync(new RouterServiceValidator.ValidationStatusCallback() {
+ @Override
+ public void onFinishedValidation(boolean valid, ComponentName name) {
+ Log.d(TAG, "onFinishedValidation: valid=" + valid + "; componentName=" + name);
+ // return value does not matter when security is off.
+ cond.open();
+ }
+ });
+ cond.block();
+ }
+
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java
index 41202fab6..b0ff164cd 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java
@@ -44,6 +44,7 @@ import android.util.Log;
import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.managers.audio.AudioStreamManager;
import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.FileManagerConfig;
import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate;
import com.smartdevicelink.managers.lockscreen.LockScreenConfig;
@@ -120,6 +121,7 @@ public class SdlManager extends BaseSdlManager{
private SdlManagerListener managerListener;
private List<Class<? extends SdlSecurityBase>> sdlSecList;
private LockScreenConfig lockScreenConfig;
+ private FileManagerConfig fileManagerConfig;
private ServiceEncryptionListener serviceEncryptionListener;
// Managers
@@ -308,7 +310,7 @@ public class SdlManager extends BaseSdlManager{
protected void initialize(){
// Instantiate sub managers
this.permissionManager = new PermissionManager(_internalInterface);
- this.fileManager = new FileManager(_internalInterface, context);
+ this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig);
if (lockScreenConfig.isEnabled()) {
this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface);
}
@@ -513,6 +515,8 @@ public class SdlManager extends BaseSdlManager{
protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; }
+ protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; }
+
// SENDING REQUESTS
/**
@@ -863,6 +867,19 @@ public class SdlManager extends BaseSdlManager{
}
@Override
+ public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() {
+ return proxy.getRegisterAppInterfaceResponse();
+ }
+
+ @Override
+ public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) {
+ if (proxy != null && proxy.getSystemCapabilityManager() != null) {
+ return proxy.getSystemCapabilityManager().getCapability(systemCapabilityType, scListener, forceUpdate);
+ }
+ return null;
+ }
+
+ @Override
public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){
return proxy.isCapabilitySupported(systemCapabilityType);
}
@@ -1030,6 +1047,17 @@ public class SdlManager extends BaseSdlManager{
}
/**
+ * Sets the FileManagerConfig for the session.<br>
+ * <strong>Note: If not set, the default configuration value of 1 will be set for
+ * artworkRetryCount and fileRetryCount in FileManagerConfig</strong>
+ * @param fileManagerConfig - configuration options
+ */
+ public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){
+ sdlManager.fileManagerConfig = fileManagerConfig;
+ 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
@@ -1181,6 +1209,11 @@ public class SdlManager extends BaseSdlManager{
sdlManager.lockScreenConfig = new LockScreenConfig();
}
+ if(sdlManager.fileManagerConfig == null){
+ //if FileManagerConfig is not set use default
+ sdlManager.fileManagerConfig = new FileManagerConfig();
+ }
+
if (sdlManager.hmiLanguage == null){
sdlManager.hmiLanguage = Language.EN_US;
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java
index a07653414..3e1702346 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java
@@ -65,6 +65,7 @@ public class FileManager extends BaseFileManager {
private final WeakReference<Context> context;
+ @Deprecated
public FileManager(ISdl internalInterface, Context context) {
// setup
@@ -73,6 +74,18 @@ public class FileManager extends BaseFileManager {
}
/**
+ * Constructor for FileManager
+ * @param internalInterface an instance of the ISdl interface that can be used for common SDL operations (sendRpc, addRpcListener, etc)
+ * @param context an instances of Context interface to global information for application
+ * @param fileManagerConfig an instance of the FileManagerConfig gives access to artworkRetryCount and fileRetryCount to let us if those file types can be re-upload if they fail
+ */
+ public FileManager(ISdl internalInterface, Context context, FileManagerConfig fileManagerConfig) {
+ // setup
+ super(internalInterface, fileManagerConfig);
+ this.context = new WeakReference<>(context);
+ }
+
+ /**
* 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
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
index e7db70ee6..5f14cb2ed 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
@@ -51,38 +51,38 @@ public class SdlArtwork extends SdlFile implements Cloneable{
/**
* Creates a new instance of SdlArtwork
*/
- public SdlArtwork(){}
+ public SdlArtwork() {}
/**
* Creates a new instance of SdlArtwork
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param id an int value representing the android resource id of the file
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, int id, boolean persistentFile) {
+ public SdlArtwork(String fileName, @NonNull FileType fileType, int id, boolean persistentFile) {
super(fileName, fileType, id, persistentFile);
}
/**
* Creates a new instance of SdlArtwork
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param uri a URI value representing a file's location. Currently, it only supports local files
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, Uri uri, boolean persistentFile) {
+ public SdlArtwork(String fileName, @NonNull FileType fileType, Uri uri, boolean persistentFile) {
super(fileName, fileType, uri, persistentFile);
}
/**
* Creates a new instance of SdlArtwork
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param data a byte array representing the data of the file
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- public SdlArtwork(@NonNull String fileName, @NonNull FileType fileType, byte[] data, boolean persistentFile) {
+ public SdlArtwork(String fileName, @NonNull FileType fileType, byte[] data, boolean persistentFile) {
super(fileName, fileType, data, persistentFile);
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java
index 3635c9551..5d7e73f5c 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlFile.java
@@ -38,63 +38,69 @@ import android.support.annotation.NonNull;
import com.smartdevicelink.proxy.rpc.enums.FileType;
import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
/**
* A class representing data to be uploaded to core
*/
public class SdlFile{
- private String fileName;
- private int id = -1;
- private Uri uri;
- private byte[] fileData;
- private FileType fileType;
- private boolean persistentFile;
- private boolean isStaticIcon;
+ private String fileName;
+ private int id = -1;
+ private Uri uri;
+ private byte[] fileData;
+ private FileType fileType;
+ private boolean persistentFile;
+ private boolean isStaticIcon;
+ private boolean shouldAutoGenerateName;
+ // Overwrite property by default is set to true in SdlFile constructors indicating that a file can be overwritten
+ private boolean overwrite = true;
/**
* Creates a new instance of SdlFile
*/
- public SdlFile(){}
+ public SdlFile() { }
/**
* Creates a new instance of SdlFile
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param id an int value representing the android resource id of the file
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- 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(String fileName, @NonNull FileType fileType, int id, boolean persistentFile){
+ setName(fileName);
+ setType(fileType);
+ setResourceId(id);
+ setPersistent(persistentFile);
}
/**
* Creates a new instance of SdlFile
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param uri a URI value representing a file's location. Currently, it only supports local files
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- 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(String fileName, @NonNull FileType fileType, Uri uri, boolean persistentFile){
+ setName(fileName);
+ setType(fileType);
+ setUri(uri);
+ setPersistent(persistentFile);
}
/**
* Creates a new instance of SdlFile
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
* @param fileType a FileType enum value representing the type of the file
* @param data a byte array representing the data of the file
* @param persistentFile a boolean value that indicates if the file is meant to persist between sessions / ignition cycles
*/
- 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(String fileName, @NonNull FileType fileType, byte[] data, boolean persistentFile){
+ setName(fileName);
+ setType(fileType);
+ setFileData(data);
+ setPersistent(persistentFile);
}
/**
@@ -102,18 +108,30 @@ public class SdlFile{
* @param staticIconName a StaticIconName enum value representing the name of a static file that comes pre-shipped with the head unit
*/
public SdlFile(@NonNull StaticIconName staticIconName){
- this.fileName = staticIconName.toString();
- this.fileData = staticIconName.toString().getBytes();
- this.persistentFile = false;
- this.isStaticIcon = true;
+ setName(staticIconName.toString());
+ setFileData(staticIconName.toString().getBytes());
+ setPersistent(false);
+ setStaticIcon(true);
}
/**
* Sets the name of the file
- * @param fileName a String value representing the name that will be used to store the file in the head unit
+ * @param fileName a String value representing the name that will be used to store the file in the head unit. You can pass null if you want the library to auto generate the name
*/
- public void setName(@NonNull String fileName){
- this.fileName = fileName;
+ public void setName(String fileName) {
+ if (fileName != null) {
+ this.shouldAutoGenerateName = false;
+ this.fileName = fileName;
+ } else {
+ this.shouldAutoGenerateName = true;
+ if (this.getFileData() != null) {
+ this.fileName = generateFileNameFromData(this.getFileData());
+ } else if (this.getUri() != null) {
+ this.fileName = generateFileNameFromUri(this.getUri());
+ } else if (this.getResourceId() != 0) {
+ this.fileName = generateFileNameFromResourceId(this.getResourceId());
+ }
+ }
}
/**
@@ -130,6 +148,9 @@ public class SdlFile{
*/
public void setResourceId(int id){
this.id = id;
+ if (shouldAutoGenerateName) {
+ this.fileName = generateFileNameFromResourceId(id);
+ }
}
/**
@@ -146,6 +167,9 @@ public class SdlFile{
*/
public void setUri(Uri uri){
this.uri = uri;
+ if (shouldAutoGenerateName && uri != null) {
+ this.fileName = generateFileNameFromUri(uri);
+ }
}
/**
@@ -162,6 +186,9 @@ public class SdlFile{
*/
public void setFileData(byte[] data){
this.fileData = data;
+ if (shouldAutoGenerateName && data != null) {
+ this.fileName = generateFileNameFromData(data);
+ }
}
/**
@@ -219,4 +246,98 @@ public class SdlFile{
public boolean isStaticIcon() {
return isStaticIcon;
}
-} \ No newline at end of file
+
+ /**
+ * Gets the overwrite property for an SdlFile by default its set to true
+ * @return a boolean value that indicates if a file can be overwritten.
+ */
+ public boolean getOverwrite() {
+ return overwrite;
+ }
+
+ /**
+ * Sets the overwrite property for an SdlFile by default its set to true
+ * @param overwrite a boolean value that indicates if a file can be overwritten
+ */
+ public void setOverwrite(boolean overwrite) {
+ this.overwrite = overwrite;
+ }
+
+ /**
+ * Generates a file name from data by hashing the data and returning the last 16 chars
+ * @param data a byte array representing the data of the file
+ * @return a String value representing the name that will be used to store the file in the head unit
+ */
+ private String generateFileNameFromData(@NonNull byte[] data) {
+ String result;
+ MessageDigest messageDigest;
+ try {
+ messageDigest = MessageDigest.getInstance("md5");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ return null;
+ }
+ byte[] hash = new byte[0];
+ if (messageDigest != null) {
+ hash = messageDigest.digest(data);
+ }
+ StringBuilder stringBuilder = new StringBuilder(2 * hash.length);
+ for (byte b : hash) {
+ stringBuilder.append(String.format("%02x", b & 0xff));
+ }
+ String hashString = stringBuilder.toString();
+ result = hashString.substring(hashString.length() - 16);
+ return result;
+ }
+
+ /**
+ * Generates a file name from uri by hashing the uri string and returning the last 16 chars
+ * @param uri a URI value representing a file's location
+ * @return a String value representing the name that will be used to store the file in the head unit
+ */
+ private String generateFileNameFromUri(@NonNull Uri uri) {
+ return generateFileNameFromData(uri.toString().getBytes());
+ }
+
+ /**
+ * Generates a file name from resourceId by hashing the id and returning the last 16 chars
+ * @param id an int value representing the android resource id of the file
+ * @return a String value representing the name that will be used to store the file in the head unit
+ */
+ private String generateFileNameFromResourceId(int id) {
+ return generateFileNameFromData("ResourceId".concat(String.valueOf(id)).getBytes());
+ }
+
+ /**
+ * Used to compile hashcode for SdlFile for use to compare in overridden equals method
+ * @return Custom hashcode of SdlFile variables
+ */
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result += ((getName() == null) ? 0 : Integer.rotateLeft(getName().hashCode(), 1));
+ result += ((getUri() == null) ? 0 : Integer.rotateLeft(getUri().hashCode(), 2));
+ result += ((getFileData() == null) ? 0 : Integer.rotateLeft(getFileData().hashCode(), 3));
+ result += ((getType() == null) ? 0 : Integer.rotateLeft(getType().hashCode(), 4));
+ result += Integer.rotateLeft(Boolean.valueOf(isStaticIcon()).hashCode(), 5);
+ result += Integer.rotateLeft(Boolean.valueOf(isPersistent()).hashCode(), 6);
+ result += Integer.rotateLeft(Integer.valueOf(getResourceId()).hashCode(), 7);
+ return result;
+ }
+
+ /**
+ * Uses our custom hashCode for SdlFile objects
+ * @param o - The object to compare
+ * @return boolean of whether the objects are the same or not
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ // if this is the same memory address, it's the same
+ if (this == o) return true;
+ // if this is not an instance of SdlFile, not the same
+ if (!(o instanceof SdlFile)) return false;
+ // return comparison
+ return hashCode() == o.hashCode();
+ }
+}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java
new file mode 100644
index 000000000..b2b8e6b14
--- /dev/null
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java
@@ -0,0 +1,214 @@
+package com.smartdevicelink.managers.lockscreen;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.smartdevicelink.util.AndroidTools;
+import com.smartdevicelink.util.DebugTool;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * <strong>LockScreenDeviceIconManager</strong> <br>
+ *
+ * The LockScreenDeviceIconManager handles the logic of caching and retrieving cached lock screen icons <br>
+ *
+ */
+class LockScreenDeviceIconManager {
+
+ private Context context;
+ private static final String SDL_DEVICE_STATUS_SHARED_PREFS = "sdl.lockScreenIcon";
+ private static final String STORED_ICON_DIRECTORY_PATH = "sdl/lock_screen_icon/";
+
+ interface OnIconRetrievedListener {
+ void onImageRetrieved(Bitmap icon);
+ void onError(String info);
+ }
+
+ LockScreenDeviceIconManager(Context context) {
+ this.context = context;
+ File lockScreenDirectory = new File(context.getCacheDir(), STORED_ICON_DIRECTORY_PATH);
+ lockScreenDirectory.mkdirs();
+ }
+
+ /**
+ * Will try to return a lock screen icon either from cache or downloaded
+ * if it fails iconRetrievedListener.OnError will be called with corresponding error message
+ * @param iconURL url that the lock screen icon is downloaded from
+ * @param iconRetrievedListener an interface that will implement onIconReceived and OnError methods
+ */
+ void retrieveIcon(String iconURL, OnIconRetrievedListener iconRetrievedListener) {
+ Bitmap icon = null;
+ try {
+ if (isIconCachedAndValid(iconURL)) {
+ DebugTool.logInfo("Icon Is Up To Date");
+ icon = getFileFromCache(iconURL);
+ if (icon == null) {
+ DebugTool.logInfo("Icon from cache was null, attempting to re-download");
+ icon = AndroidTools.downloadImage(iconURL);
+ if (icon != null) {
+ saveFileToCache(icon, iconURL);
+ } else {
+ iconRetrievedListener.onError("Icon downloaded was null");
+ return;
+ }
+ }
+ iconRetrievedListener.onImageRetrieved(icon);
+ } else {
+ // The icon is unknown or expired. Download the image, save it to the cache, and update the archive file
+ DebugTool.logInfo("Lock Screen Icon Update Needed");
+ icon = AndroidTools.downloadImage(iconURL);
+ if (icon != null) {
+ saveFileToCache(icon, iconURL);
+ iconRetrievedListener.onImageRetrieved(icon);
+ } else {
+ iconRetrievedListener.onError("Icon downloaded was null");
+ }
+ }
+ } catch (IOException e) {
+ iconRetrievedListener.onError("device Icon Error Downloading, Will attempt to grab cached Icon even if expired: \n" + e.toString());
+ icon = getFileFromCache(iconURL);
+ if (icon != null) {
+ iconRetrievedListener.onImageRetrieved(icon);
+ } else {
+ iconRetrievedListener.onError("Unable to retrieve icon from cache");
+ }
+ }
+ }
+
+ /**
+ * Will decide if a cached icon is available and up to date
+ * @param iconUrl url will be hashed and used to look up last updated timestamp in shared preferences
+ * @return True when icon details are in shared preferences and less than 30 days old, False if icon details are too old or not found
+ */
+ private boolean isIconCachedAndValid(String iconUrl) {
+ String iconHash = getMD5HashFromIconUrl(iconUrl);
+ SharedPreferences sharedPref = this.context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ String iconLastUpdatedTime = sharedPref.getString(iconHash, null);
+ if(iconLastUpdatedTime == null) {
+ DebugTool.logInfo("No Icon Details Found In Shared Preferences");
+ return false;
+ } else {
+ DebugTool.logInfo("Icon Details Found");
+ long lastUpdatedTime = 0;
+ try {
+ lastUpdatedTime = Long.parseLong(iconLastUpdatedTime);
+ } catch (NumberFormatException e) {
+ DebugTool.logInfo("Invalid time stamp stored to shared preferences, clearing cache and share preferences");
+ clearIconDirectory();
+ sharedPref.edit().clear().commit();
+ }
+ long currentTime = System.currentTimeMillis();
+
+ long timeDifference = currentTime - lastUpdatedTime;
+ long daysBetweenLastUpdate = timeDifference / (1000 * 60 * 60 * 24);
+ return daysBetweenLastUpdate < 30;
+ }
+ }
+
+ /**
+ * Will try to save icon to cache
+ * @param icon the icon bitmap that should be saved to cache
+ * @param iconUrl the url where the icon was retrieved will be hashed and used for file and file details lookup
+ */
+ private void saveFileToCache(Bitmap icon, String iconUrl) {
+ String iconHash = getMD5HashFromIconUrl(iconUrl);
+ File f = new File(this.context.getCacheDir() + "/" + STORED_ICON_DIRECTORY_PATH, iconHash);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ icon.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
+ byte[] bitmapData = bos.toByteArray();
+
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f);
+ fos.write(bitmapData);
+ fos.flush();
+ fos.close();
+ writeDeviceIconParametersToSharedPreferences(iconHash);
+ } catch (Exception e) {
+ DebugTool.logError("Failed to save icon to cache");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Will try to retrieve icon bitmap from cached directory
+ * @param iconUrl the url where the icon was retrieved will be hashed and used to look up file location
+ * @return bitmap of device icon or null if it fails to find the icon or read from shared preferences
+ */
+ private Bitmap getFileFromCache(String iconUrl) {
+ String iconHash = getMD5HashFromIconUrl(iconUrl);
+ SharedPreferences sharedPref = this.context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ String iconLastUpdatedTime = sharedPref.getString(iconHash, null);
+
+ if (iconLastUpdatedTime != null) {
+ Bitmap cachedIcon = BitmapFactory.decodeFile(this.context.getCacheDir() + "/" + STORED_ICON_DIRECTORY_PATH + "/" + iconHash);
+ if(cachedIcon == null) {
+ DebugTool.logError("Failed to get Bitmap from decoding file cache");
+ clearIconDirectory();
+ sharedPref.edit().clear().commit();
+ return null;
+ } else {
+ return cachedIcon;
+ }
+ } else {
+ DebugTool.logError("Failed to get shared preferences");
+ return null;
+ }
+ }
+
+ /**
+ * Will write information about the icon to shared preferences
+ * icon information will have a look up key of the hashed icon url and the current timestamp to indicated when the icon was last updated.
+ * @param iconHash the url where the icon was retrieved will be hashed and used lookup key
+ */
+ private void writeDeviceIconParametersToSharedPreferences(String iconHash) {
+ SharedPreferences sharedPref = this.context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString(iconHash, String.valueOf(System.currentTimeMillis()));
+ editor.commit();
+ }
+
+ /**
+ * Create an MD5 hash of the icon url for file storage and lookup/shared preferences look up
+ * @param iconUrl the url where the icon was retrieved
+ * @return MD5 hash of the icon URL
+ */
+ private String getMD5HashFromIconUrl(String iconUrl) {
+ String iconHash = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] messageDigest = md.digest(iconUrl.getBytes());
+ BigInteger no = new BigInteger(1, messageDigest);
+ String hashtext = no.toString(16);
+ while (hashtext.length() < 32) {
+ hashtext = "0" + hashtext;
+ }
+ iconHash = hashtext;
+ } catch (NoSuchAlgorithmException e) {
+ DebugTool.logError("Unable to hash icon url");
+ e.printStackTrace();
+ }
+ return iconHash;
+ }
+
+ /**
+ * Clears all files in the directory where lock screen icons are cached
+ */
+ private void clearIconDirectory() {
+ File iconDir = new File(context.getCacheDir() + "/" + STORED_ICON_DIRECTORY_PATH);
+ if (iconDir.listFiles() != null) {
+ for (File child : iconDir.listFiles()) {
+ child.delete();
+ }
+ }
+ }
+}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java
index 30ed1b575..2e81894ed 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java
@@ -54,9 +54,8 @@ import com.smartdevicelink.proxy.rpc.enums.LockScreenStatus;
import com.smartdevicelink.proxy.rpc.enums.PredefinedWindows;
import com.smartdevicelink.proxy.rpc.enums.RequestType;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
-import com.smartdevicelink.util.AndroidTools;
+import com.smartdevicelink.util.DebugTool;
-import java.io.IOException;
import java.lang.ref.WeakReference;
/**
@@ -82,11 +81,14 @@ public class LockScreenManager extends BaseSubManager {
private boolean mLockScreenHasBeenDismissed, lockscreenDismissReceiverRegistered, receivedFirstDDNotification;
private String mLockscreenWarningMsg;
private BroadcastReceiver mLockscreenDismissedReceiver;
+ private LockScreenDeviceIconManager mLockScreenDeviceIconManager;
public LockScreenManager(LockScreenConfig lockScreenConfig, Context context, ISdl internalInterface){
super(internalInterface);
this.context = new WeakReference<>(context);
+ this.mLockScreenDeviceIconManager = new LockScreenDeviceIconManager(context);
+
// set initial class variables
hmiLevel = HMILevel.HMI_NONE;
@@ -231,7 +233,7 @@ public class LockScreenManager extends BaseSubManager {
if (msg.getRequestType() == RequestType.LOCK_SCREEN_ICON_URL &&
msg.getUrl() != null) {
// send intent to activity to download icon from core
- deviceIconUrl = msg.getUrl();
+ deviceIconUrl = msg.getUrl().replace("http://", "https://");
downloadDeviceIcon(deviceIconUrl);
}
}
@@ -375,17 +377,25 @@ public class LockScreenManager extends BaseSubManager {
new Thread(new Runnable(){
@Override
public void run(){
- try{
- deviceLogo = AndroidTools.downloadImage(url);
- Intent intent = new Intent(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_DOWNLOADED);
- intent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled);
- intent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo);
- if (context.get() != null) {
- context.get().sendBroadcast(intent);
+ mLockScreenDeviceIconManager.retrieveIcon(url, new LockScreenDeviceIconManager.OnIconRetrievedListener() {
+ @Override
+ public void onImageRetrieved(Bitmap icon) {
+ deviceLogo = icon;
+ if(deviceLogo != null) {
+ Intent intent = new Intent(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_DOWNLOADED);
+ intent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled);
+ intent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo);
+ if (context.get() != null) {
+ context.get().sendBroadcast(intent);
+ }
+ }
}
- }catch(IOException e){
- Log.e(TAG, "device Icon Error Downloading");
- }
+
+ @Override
+ public void onError(String info) {
+ DebugTool.logError(info);
+ }
+ });
}
}).start();
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java
index bb257b915..b6f49a9a4 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java
@@ -65,6 +65,7 @@ import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.PredefinedWindows;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.enums.TouchType;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingState;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
import com.smartdevicelink.streaming.video.VideoStreamingParameters;
@@ -89,12 +90,13 @@ public class VideoStreamManager extends BaseVideoStreamManager {
private float[] touchScalar = {1.0f,1.0f}; //x, y
private HapticInterfaceManager hapticManager;
private SdlMotionEvent sdlMotionEvent = null;
- private HMILevel hmiLevel;
+ private OnHMIStatus currentOnHMIStatus;
private StreamingStateMachine stateMachine;
private VideoStreamingParameters parameters;
private IVideoStreamListener streamListener;
private boolean isTransportAvailable = false;
private boolean hasStarted;
+ private String vehicleMake = null;
// INTERNAL INTERFACES
@@ -113,7 +115,7 @@ public class VideoStreamManager extends BaseVideoStreamManager {
return;
}
VideoStreamingCapability capability = (VideoStreamingCapability) internalInterface.getCapability(SystemCapabilityType.VIDEO_STREAMING);
- if(capability != null && capability.getIsHapticSpatialDataSupported()){
+ if(capability != null && Boolean.TRUE.equals(capability.getIsHapticSpatialDataSupported())){
hapticManager = new HapticInterfaceManager(internalInterface);
}
startEncoder();
@@ -125,10 +127,11 @@ public class VideoStreamManager extends BaseVideoStreamManager {
@Override
public void onServiceEnded(SdlSession session, SessionType type) {
if(SessionType.NAV.equals(type)){
- stateMachine.transitionToState(StreamingStateMachine.NONE);
if(remoteDisplay!=null){
stopStreaming();
}
+ stateMachine.transitionToState(StreamingStateMachine.NONE);
+ transitionToState(SETTING_UP);
}
}
@@ -144,13 +147,18 @@ public class VideoStreamManager extends BaseVideoStreamManager {
@Override
public void onNotified(RPCNotification notification) {
if(notification != null){
- OnHMIStatus onHMIStatus = (OnHMIStatus)notification;
+ OnHMIStatus onHMIStatus = (OnHMIStatus) notification;
if (onHMIStatus.getWindowID() != null && onHMIStatus.getWindowID() != PredefinedWindows.DEFAULT_WINDOW.getValue()) {
return;
}
- hmiLevel = onHMIStatus.getHmiLevel();
- if(hmiLevel.equals(HMILevel.HMI_FULL)){
- checkState();
+ OnHMIStatus prevOnHMIStatus = currentOnHMIStatus;
+ currentOnHMIStatus = onHMIStatus;
+ if (!HMILevel.HMI_NONE.equals(currentOnHMIStatus.getHmiLevel()) && VideoStreamManager.this.parameters == null) {
+ getVideoStreamingParams();
+ }
+ checkState();
+ if (hasStarted && (isHMIStateVideoStreamCapable(prevOnHMIStatus)) && (!isHMIStateVideoStreamCapable(currentOnHMIStatus))) {
+ internalInterface.stopVideoService();
}
}
}
@@ -171,12 +179,14 @@ public class VideoStreamManager extends BaseVideoStreamManager {
};
// MANAGER APIs
-
public VideoStreamManager(ISdl internalInterface){
super(internalInterface);
+ if(internalInterface != null && internalInterface.getRegisterAppInterfaceResponse() != null &&
+ internalInterface.getRegisterAppInterfaceResponse().getVehicleType() != null) {
+ vehicleMake = internalInterface.getRegisterAppInterfaceResponse().getVehicleType().getMake();
+ }
virtualDisplayEncoder = new VirtualDisplayEncoder();
- hmiLevel = HMILevel.HMI_NONE;
// Listen for video service events
internalInterface.addServiceListener(SessionType.NAV, serviceListener);
@@ -191,7 +201,6 @@ public class VideoStreamManager extends BaseVideoStreamManager {
@Override
public void start(CompletionListener listener) {
isTransportAvailable = internalInterface.isTransportForServiceAvailable(SessionType.NAV);
- getVideoStreamingParams();
checkState();
super.start(listener);
}
@@ -199,21 +208,26 @@ public class VideoStreamManager extends BaseVideoStreamManager {
private synchronized void checkState(){
if(this.getState() == SETTING_UP
&& isTransportAvailable
- && hmiLevel != null
- && hmiLevel.equals(HMILevel.HMI_FULL)
+ && isHMIStateVideoStreamCapable(currentOnHMIStatus)
&& parameters != null){
stateMachine.transitionToState(StreamingStateMachine.READY);
transitionToState(READY);
}
}
+ boolean isHMIStateVideoStreamCapable(OnHMIStatus onHMIStatus) {
+ HMILevel hmiLevel = (onHMIStatus != null && onHMIStatus.getHmiLevel() != null) ? onHMIStatus.getHmiLevel() : HMILevel.HMI_NONE;
+ VideoStreamingState videoStreamingState = (onHMIStatus != null && onHMIStatus.getVideoStreamingState() != null) ? onHMIStatus.getVideoStreamingState() : VideoStreamingState.STREAMABLE;
+ return (hmiLevel.equals(HMILevel.HMI_FULL) || hmiLevel.equals(HMILevel.HMI_LIMITED)) && videoStreamingState.equals(VideoStreamingState.STREAMABLE);
+ }
+
private void getVideoStreamingParams(){
if(internalInterface.getProtocolVersion().getMajor() >= 5) {
internalInterface.getCapability(SystemCapabilityType.VIDEO_STREAMING, new OnSystemCapabilityListener() {
@Override
public void onCapabilityRetrieved(Object capability) {
VideoStreamingParameters params = new VideoStreamingParameters();
- params.update((VideoStreamingCapability)capability); //Streaming parameters are ready time to stream
+ params.update((VideoStreamingCapability)capability, vehicleMake); //Streaming parameters are ready time to stream
VideoStreamManager.this.parameters = params;
checkState();
@@ -265,7 +279,7 @@ public class VideoStreamManager extends BaseVideoStreamManager {
@Override
public void onCapabilityRetrieved(Object capability) {
VideoStreamingParameters params = new VideoStreamingParameters();
- params.update((VideoStreamingCapability)capability); //Streaming parameters are ready time to stream
+ params.update((VideoStreamingCapability)capability, vehicleMake); //Streaming parameters are ready time to stream
startStreaming(params, encrypted);
}
@@ -298,13 +312,12 @@ public class VideoStreamManager extends BaseVideoStreamManager {
*/
protected void startStreaming(VideoStreamingParameters parameters, boolean encrypted){
this.parameters = parameters;
- if(hmiLevel != HMILevel.HMI_FULL){
- Log.e(TAG, "Cannot start video service if HMILevel is not FULL.");
+ if (!isHMIStateVideoStreamCapable(currentOnHMIStatus)) {
+ Log.e(TAG, "Cannot start video service in the current HMI status");
return;
}
//Start the video service
this.internalInterface.startVideoService(parameters, encrypted);
-
}
/**
@@ -394,7 +407,7 @@ public class VideoStreamManager extends BaseVideoStreamManager {
* @return boolean (true = yes, false = no)
*/
public boolean isStreaming(){
- return (stateMachine.getState() == StreamingStateMachine.STARTED) && (hmiLevel == HMILevel.HMI_FULL);
+ return (stateMachine.getState() == StreamingStateMachine.STARTED) && (isHMIStateVideoStreamCapable(currentOnHMIStatus));
}
/**
@@ -402,7 +415,7 @@ public class VideoStreamManager extends BaseVideoStreamManager {
* @return boolean (true = not paused, false = paused)
*/
public boolean isPaused(){
- return (hasStarted && stateMachine.getState() == StreamingStateMachine.STOPPED) || (hmiLevel != HMILevel.HMI_FULL);
+ return (hasStarted && stateMachine.getState() == StreamingStateMachine.STOPPED) || (!isHMIStateVideoStreamCapable(currentOnHMIStatus));
}
/**
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCRequestFactory.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCRequestFactory.java
index e787fb77d..d046fe5ad 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCRequestFactory.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCRequestFactory.java
@@ -1022,7 +1022,7 @@ public class RPCRequestFactory {
{
DeviceInfo msg = new DeviceInfo();
msg.setHardware(android.os.Build.MODEL);
- msg.setOs(DeviceInfo.DEVICE_OS);
+ msg.setOs("Android");
msg.setOsVersion(Build.VERSION.RELEASE);
msg.setCarrier(carrierName);
return msg;
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
index 4a0668617..ad9969163 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
@@ -445,11 +445,24 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
@Override
+ public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() {
+ return SdlProxyBase.this.getRegisterAppInterfaceResponse();
+ }
+
+ @Override
public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) {
SdlProxyBase.this.getCapability(systemCapabilityType, scListener);
}
@Override
+ public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) {
+ if (_systemCapabilityManager != null) {
+ return _systemCapabilityManager.getCapability(systemCapabilityType, scListener, forceUpdate);
+ }
+ return null;
+ }
+
+ @Override
public SdlMsgVersion getSdlMsgVersion(){
try {
return SdlProxyBase.this.getSdlMsgVersion();
@@ -6721,7 +6734,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setHardware(android.os.Build.MODEL);
- deviceInfo.setOs(DeviceInfo.DEVICE_OS);
+ deviceInfo.setOs("Android");
deviceInfo.setOsVersion(Build.VERSION.RELEASE);
deviceInfo.setCarrier(carrierName);
@@ -8368,7 +8381,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
return;
}
VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING);
- if(capability != null && capability.getIsHapticSpatialDataSupported()){
+ if(capability != null && Boolean.TRUE.equals(capability.getIsHapticSpatialDataSupported())){
hapticManager = new HapticInterfaceManager(internalInterface);
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java
index 7ebcec1c2..d72987a88 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java
@@ -249,7 +249,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{
if(!stateProgress){//We are trying to weed through the bad packet info until we get something
//Log.w(TAG, "Packet State Machine did not move forward from state - "+ psm.getState()+". PSM being Reset.");
psm.reset();
- buffer = new byte[READ_BUFFER_SIZE];
+ continue; //Move to the next iteration of the loop
}
if(psm.getState() == SdlPsm.FINISHED_STATE){
@@ -259,9 +259,11 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{
packet.setTransportRecord(getTransportRecord());
handler.obtainMessage(SdlRouterService.MESSAGE_READ, packet).sendToTarget();
}
- //We put a trace statement in the message read so we can avoid all the extra bytes
+ //Reset the PSM now that we have a finished packet.
+ //We will continue to loop through the data to see if any other packet
+ //is present.
psm.reset();
- buffer = new byte[READ_BUFFER_SIZE]; //FIXME just do an array copy and send off
+ continue; //Move to the next iteration of the loop
}
}
} catch (IOException e) {
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
index 06729d62a..227b0b894 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
@@ -43,13 +43,18 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.os.AsyncTask;
import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
import android.support.annotation.NonNull;
import android.util.Log;
import com.smartdevicelink.util.AndroidTools;
+import com.smartdevicelink.util.DebugTool;
import com.smartdevicelink.util.HttpRequestTask;
import com.smartdevicelink.util.HttpRequestTask.HttpRequestTaskCallback;
+import com.smartdevicelink.util.ServiceFinder;
import org.json.JSONArray;
import org.json.JSONException;
@@ -60,6 +65,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
+import java.util.Vector;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* This class will tell us if the currently running router service is valid or not.
@@ -138,11 +148,15 @@ public class RouterServiceValidator {
setSecurityLevel(config.securityLevel);
inDebugMode = inDebugMode();
}
-
+
/**
* Main function to call to ensure we are connecting to a validated router service
* @return whether or not the currently running router service can be trusted.
+ *
+ * Due to SDL 0220 proposal, we should use validateAsync always.
+ * This function remains only for backward compatibility.
*/
+ @Deprecated
public boolean validate(){
if(securityLevel == -1){
@@ -201,6 +215,187 @@ public class RouterServiceValidator {
}
/**
+ * Asynchronously validate the target RouterService, which includes finding the right RouterService.
+ * @param callback: callback gets called when validation finishes.
+ */
+ public void validateAsync(final ValidationStatusCallback callback) {
+ if(securityLevel == -1){
+ securityLevel = getSecurityLevel(context);
+ }
+
+ final PackageManager pm = context.getPackageManager();
+ //Grab the package for the currently running router service. We need this call regardless of if we are in debug mode or not.
+
+ if(this.service != null){
+ DebugTool.logInfo("Supplied service name of " + this.service.getClassName());
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !isServiceRunning(context,this.service)){
+ //This means our service isn't actually running, so set to null. Hopefully we can find a real router service after this.
+ service = null;
+ DebugTool.logWarning("Supplied service is not actually running.");
+ } else {
+ // If the running router service is created by this app, the validation is good by default
+ if (this.service.getPackageName().equals(context.getPackageName()) && callback != null) {
+ callback.onFinishedValidation(true, this.service);
+ return;
+ }
+ }
+ }
+
+ if(this.service == null){
+ DebugTool.logInfo("about finding the best Router by using retrieveBestRouterServiceName");
+ new FindRouterTask(new FindConnectedRouterCallback() {
+ @Override
+ public void onFound(ComponentName component) {
+ DebugTool.logInfo("FindConnectedRouterCallback.onFound got called. Package=" + component);
+ checkTrustedRouter(callback, pm, component);
+ }
+
+ @Override
+ public void onFailed() {
+ DebugTool.logInfo("FindConnectedRouterCallback.onFailed was called");
+ if (callback != null) {
+ callback.onFinishedValidation(false, null);
+ }
+ }
+ }).execute(this.context);
+ } else {
+ // already found the RouterService
+ checkTrustedRouter(callback, pm, service);
+ }
+
+ }
+
+ /**
+ * checkTrustedRouter: This checks to see if the given component is Trusted RouterService,
+ * and calls ValidationStatusCallback#onFinishedValidation.
+ *
+ * @param callback
+ * @param pm
+ * @param component
+ */
+ private void checkTrustedRouter(final ValidationStatusCallback callback, final PackageManager pm, final ComponentName component) {
+ String packageName = appPackageForComponentName(component, pm);
+ boolean valid = (securityLevel == MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF);
+
+ if(!valid && packageName!=null){//Make sure there is a service running
+ if(wasInstalledByAppStore(packageName)){ //Was this package installed from a trusted app store
+ if( isTrustedPackage(packageName, pm)){//Is this package on the list of trusted apps.
+ valid = true;
+ }
+ }
+ }
+ if (callback != null) {
+ callback.onFinishedValidation(valid, component);
+ if (valid) {
+ synchronized (this) {
+ this.service = component;
+ }
+ }
+ }
+ }
+ /**
+ * This method retrieves the best routerservice name asynchronously.
+ * @param context
+ */
+ //private void retrieveBestRouterServiceName(Context context) {
+ // FindRouterTask task = new FindRouterTask(null);
+ // task.execute(context);
+ //}
+
+ /**
+ * FindRouterTask: AsyncTask to find the connected RouterService.
+ */
+ class FindRouterTask extends AsyncTask<Context, Void, ComponentName> {
+ FindConnectedRouterCallback mCallback;
+ final Handler mHandler = new Handler(Looper.getMainLooper());
+ final Integer TIMEOUT_MSEC = 10000; // 10 sec
+
+ FindRouterTask(FindConnectedRouterCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ protected ComponentName doInBackground(final Context... contexts) {
+ // let's use ServiceFinder here
+ final BlockingQueue<ComponentName> serviceQueue = new LinkedBlockingQueue<>();
+ final AtomicInteger _counter = new AtomicInteger(0);
+ Context context = contexts[0];
+ final Thread _currentThread = Thread.currentThread();
+ new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() {
+ @Override
+ public void onComplete(Vector<ComponentName> routerServices) {
+ // OK, we found the routerServices. Let's see one-by-one.
+ if (routerServices == null || routerServices.isEmpty()) {
+ _currentThread.interrupt();
+ return;
+ }
+
+
+ final int numServices = routerServices.size();
+ for (ComponentName name: routerServices) {
+ final SdlRouterStatusProvider provider = new SdlRouterStatusProvider(contexts[0], name, new SdlRouterStatusProvider.ConnectedStatusCallback() {
+ @Override
+ public void onConnectionStatusUpdate(final boolean connected, final ComponentName service, final Context context) {
+ // make sure this part runs on main thread.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _counter.incrementAndGet();
+ if (connected) {
+ DebugTool.logInfo("We found the connected service (" + service + "); currentThread is " + Thread.currentThread().getName());
+ serviceQueue.add(service);
+ } else if (_counter.get() == numServices) {
+ DebugTool.logInfo("SdlRouterStatusProvider returns service=" + service + "; connected=" + connected);
+ _currentThread.interrupt();
+ }
+ }
+ });
+ }
+ });
+ DebugTool.logInfo("about checkIsConnected; thread=" + Thread.currentThread().getName());
+ provider.checkIsConnected();
+ }
+ }
+ });
+
+ try {
+ ComponentName found = serviceQueue.poll(TIMEOUT_MSEC, TimeUnit.MILLISECONDS);
+ return found;
+ } catch(InterruptedException e) {
+ DebugTool.logInfo("FindRouterTask was interrupted because connected Router cannot be found");
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(ComponentName componentName) {
+ DebugTool.logInfo("onPostExecute componentName=" + componentName);
+ super.onPostExecute(componentName);
+ if (mCallback != null) {
+ if (componentName != null && componentName.getPackageName() != null && componentName.getPackageName().length() != 0) {
+ mCallback.onFound(componentName);
+ } else {
+ mCallback.onFailed();
+ }
+ }
+ }
+
+ }
+
+ /**
+ * FindConnectedRouterCallback
+ * Used internally for validating router service.
+ */
+ private interface FindConnectedRouterCallback {
+ void onFound(ComponentName component);
+ void onFailed();
+ }
+
+ interface ValidationStatusCallback {
+ void onFinishedValidation(boolean valid, ComponentName name);
+ }
+
+ /**
* This will ensure that all router services are aware that there are no valid router services running and should start up
*/
private void wakeUpRouterServices(){
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
index 92f19e56d..ba1cc80a0 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
@@ -303,7 +303,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
* main looper to continue forward. This still leaves the SdlRouterService killed, but prevents
* an ANR to the app that makes the startForegroundService call.
*/
- static private void setForegroundExceptionHandler() {
+ static protected void setForegroundExceptionHandler() {
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
if(defaultUncaughtExceptionHandler != foregroundExceptionHandler){
foregroundExceptionHandler = new Thread.UncaughtExceptionHandler() {
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
index 3abd61094..3313fd0f3 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
@@ -69,6 +69,7 @@ import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.service.notification.StatusBarNotification;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
@@ -138,7 +139,7 @@ public class SdlRouterService extends Service{
/**
* <b> NOTE: DO NOT MODIFY THIS UNLESS YOU KNOW WHAT YOU'RE DOING.</b>
*/
- protected static final int ROUTER_SERVICE_VERSION_NUMBER = 10;
+ protected static final int ROUTER_SERVICE_VERSION_NUMBER = 11;
private static final String ROUTER_SERVICE_PROCESS = "com.smartdevicelink.router";
@@ -1343,6 +1344,7 @@ public class SdlRouterService extends Service{
// If this is the first time the service has ever connected to this device we want
// to ensure we have a record of it
setSDLConnectedStatus(address, false);
+ return FOREGROUND_TIMEOUT;
}
}
// If this is a new device or hasn't connected through SDL we want to limit the exposure
@@ -1443,8 +1445,9 @@ public class SdlRouterService extends Service{
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
- if(chronometerLength > 0 && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ if(chronometerLength > (FOREGROUND_TIMEOUT/1000) && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//The countdown method is only available in SDKs >= 24
+ // Only add countdown if it is over the min timeout
builder.setWhen(chronometerLength + System.currentTimeMillis());
builder.setUsesChronometer(true);
builder.setChronometerCountDown(true);
@@ -1515,7 +1518,23 @@ public class SdlRouterService extends Service{
private void exitForeground(){
synchronized (NOTIFICATION_LOCK) {
if (isForeground && !isPrimaryTransportConnected()) { //Ensure that the service is in the foreground and no longer connected to a transport
- this.stopForeground(true);
+ DebugTool.logInfo("SdlRouterService to exit foreground");
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ this.stopForeground(Service.STOP_FOREGROUND_DETACH);
+ }else{
+ stopForeground(false);
+ }
+ NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager!= null){
+ try {
+ notificationManager.cancelAll();
+ if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ notificationManager.deleteNotificationChannel(SDL_NOTIFICATION_CHANNEL_ID);
+ }
+ } catch (Exception e) {
+ DebugTool.logError("Issue when removing notification and channel", e);
+ }
+ }
isForeground = false;
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
index fcd17a0fb..53e1dbbed 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
@@ -133,13 +133,14 @@ public class SdlRouterStatusProvider {
context.startService(bindingIntent);
}else {
bindingIntent.putExtra(FOREGROUND_EXTRA, true);
+ SdlBroadcastReceiver.setForegroundExceptionHandler(); //Prevent ANR in case the OS takes too long to start the service
context.startForegroundService(bindingIntent);
}
bindingIntent.setAction( TransportConstants.BIND_REQUEST_TYPE_STATUS);
return context.bindService(bindingIntent, routerConnection, Context.BIND_AUTO_CREATE);
}
-
+
private void unBindFromService(){
try{
if(context!=null && routerConnection!=null){
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java
index 19c223d87..1a0951503 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java
@@ -59,7 +59,6 @@ import java.util.List;
public class TransportManager extends TransportManagerBase{
private static final String TAG = "TransportManager";
-
TransportBrokerImpl transport;
//Legacy Transport
@@ -67,6 +66,7 @@ public class TransportManager extends TransportManagerBase{
LegacyBluetoothHandler legacyBluetoothHandler;
final WeakReference<Context> contextWeakReference;
+ final MultiplexTransportConfig mConfig;
/**
@@ -78,32 +78,40 @@ public class TransportManager extends TransportManagerBase{
public TransportManager(MultiplexTransportConfig config, TransportEventListener listener){
super(config,listener);
+ this.mConfig = config;
+
if(config.service == null) {
config.service = SdlBroadcastReceiver.consumeQueuedRouterService();
}
contextWeakReference = new WeakReference<>(config.context);
-
- RouterServiceValidator validator = new RouterServiceValidator(config);
- if(validator.validate()){
- transport = new TransportBrokerImpl(config.context, config.appId,config.service);
- }else{
- enterLegacyMode("Router service is not trusted. Entering legacy mode");
- }
}
+ /**
+ * start internally validates the target ROuterService, which was done in ctor before.
+ */
@Override
- public void start(){
- if(transport != null){
- if (!transport.start()){
- //Unable to connect to a router service
- if(transportListener != null){
- transportListener.onError("Unable to connect with the router service");
+ public void start() {
+ final RouterServiceValidator validator = new RouterServiceValidator(mConfig);
+ validator.validateAsync(new RouterServiceValidator.ValidationStatusCallback() {
+ @Override
+ public void onFinishedValidation(boolean valid, ComponentName name) {
+ DebugTool.logInfo("onFinishedValidation valid=" + valid + "; name=" + ((name == null)? "null" : name.getPackageName()));
+ if (valid) {
+ mConfig.service = name;
+ transport = new TransportBrokerImpl(contextWeakReference.get(), mConfig.appId, mConfig.service);
+ DebugTool.logInfo("TransportManager start got called; transport=" + transport);
+ if(transport != null){
+ transport.start();
+ }
+ } else {
+ enterLegacyMode("Router service is not trusted. Entering legacy mode");
+ if(legacyBluetoothTransport != null){
+ legacyBluetoothTransport.start();
+ }
}
}
- }else if(legacyBluetoothTransport != null){
- legacyBluetoothTransport.start();
- }
+ });
}
@Override
diff --git a/android/sdl_android/src/main/res/values/sdl.xml b/android/sdl_android/src/main/res/values/sdl.xml
index 2b3a85a05..16553ad29 100644
--- a/android/sdl_android/src/main/res/values/sdl.xml
+++ b/android/sdl_android/src/main/res/values/sdl.xml
@@ -2,7 +2,7 @@
<resources>
<string name="sdl_router_service_version_name" translatable="false">sdl_router_version</string>
- <integer name="sdl_router_service_version_value">10</integer>
+ <integer name="sdl_router_service_version_value">11</integer>
<string name="sdl_router_service_is_custom_name" translatable="false">sdl_custom_router</string>
</resources>