summaryrefslogtreecommitdiff
path: root/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers
diff options
context:
space:
mode:
Diffstat (limited to 'android/sdl_android/src/androidTest/java/com/smartdevicelink/managers')
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java393
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java681
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java507
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenConfigTests.java45
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java56
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/permission/PermissionManagerTests.java203
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java135
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java242
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java546
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java282
10 files changed, 3090 insertions, 0 deletions
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java
new file mode 100644
index 000000000..b1a1df0ed
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/SdlManagerTests.java
@@ -0,0 +1,393 @@
+package com.smartdevicelink.managers;
+
+import android.content.Context;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.exception.SdlException;
+import com.smartdevicelink.managers.lockscreen.LockScreenConfig;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCMessage;
+import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.RPCResponse;
+import com.smartdevicelink.proxy.SdlProxyBase;
+import com.smartdevicelink.proxy.rpc.GetAppServiceDataResponse;
+import com.smartdevicelink.proxy.rpc.GetVehicleData;
+import com.smartdevicelink.proxy.rpc.OnAppServiceData;
+import com.smartdevicelink.proxy.rpc.Show;
+import com.smartdevicelink.proxy.rpc.TemplateColorScheme;
+import com.smartdevicelink.proxy.rpc.enums.AppHMIType;
+import com.smartdevicelink.proxy.rpc.enums.Language;
+import com.smartdevicelink.proxy.rpc.enums.Result;
+import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.transport.BaseTransportConfig;
+import com.smartdevicelink.transport.TCPTransportConfig;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link com.smartdevicelink.managers.SdlManager}
+ */
+public class SdlManagerTests extends AndroidTestCase2 {
+
+ public static BaseTransportConfig transport = null;
+ private Context mTestContext;
+ private Vector<AppHMIType> appType;
+ private TemplateColorScheme templateColorScheme;
+ private int listenerCalledCounter;
+ private SdlManager sdlManager;
+ private SdlProxyBase sdlProxyBase;
+
+ // transport related
+ @SuppressWarnings("FieldCanBeLocal")
+ private int TCP_PORT = 12345;
+ @SuppressWarnings("FieldCanBeLocal")
+ private String DEV_MACHINE_IP_ADDRESS = "0.0.0.0";
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+
+ // set transport
+ transport = new TCPTransportConfig(TCP_PORT, DEV_MACHINE_IP_ADDRESS, true);
+
+ // add AppTypes
+ appType = new Vector<>();
+ appType.add(AppHMIType.DEFAULT);
+
+ // Color Scheme
+ templateColorScheme = new TemplateColorScheme();
+ templateColorScheme.setBackgroundColor(Test.GENERAL_RGBCOLOR);
+ templateColorScheme.setPrimaryColor(Test.GENERAL_RGBCOLOR);
+ templateColorScheme.setSecondaryColor(Test.GENERAL_RGBCOLOR);
+
+ sdlManager = createSampleManager("heyApp", "123456", Test.GENERAL_LOCKSCREENCONFIG);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // SETUP / HELPERS
+
+ private Context getTestContext() {
+ return mTestContext;
+ }
+
+ private SdlManager createSampleManager(String appName, String appId, LockScreenConfig lockScreenConfig){
+ SdlManager manager;
+
+ SdlManagerListener listener = new SdlManagerListener() {
+ @Override
+ public void onStart() {
+ listenerCalledCounter++;
+ }
+
+ @Override
+ public void onDestroy() {
+
+ }
+
+ @Override
+ public void onError(String info, Exception e) {
+
+ }
+ };
+
+ // build manager object - use all setters, will test using getters below
+ SdlManager.Builder builder = new SdlManager.Builder(getTestContext(),appId,appName,listener);
+ builder.setShortAppName(appName);
+ builder.setAppTypes(appType);
+ builder.setTransportType(transport);
+ builder.setLanguage(Language.EN_US);
+ builder.setDayColorScheme(templateColorScheme);
+ builder.setNightColorScheme(templateColorScheme);
+ builder.setVrSynonyms(Test.GENERAL_VECTOR_STRING);
+ builder.setTtsName(Test.GENERAL_VECTOR_TTS_CHUNKS);
+ builder.setLockScreenConfig(lockScreenConfig);
+ builder.setMinimumProtocolVersion(Test.GENERAL_VERSION);
+ builder.setMinimumRPClVersion(Test.GENERAL_VERSION);
+ manager = builder.build();
+
+ // mock SdlProxyBase and set it manually
+ sdlProxyBase = mock(SdlProxyBase.class);
+ manager.setProxy(sdlProxyBase);
+
+ return manager;
+ }
+
+ // TESTS
+
+ public void testNotNull(){
+ assertNotNull(createSampleManager("app","123456", Test.GENERAL_LOCKSCREENCONFIG));
+ }
+
+ public void testMissingAppName() {
+ try {
+ createSampleManager(null,"123456", Test.GENERAL_LOCKSCREENCONFIG);
+ } catch (IllegalArgumentException ex) {
+ assertSame(ex.getMessage(), "You must specify an app name by calling setAppName");
+ }
+ }
+
+ public void testMissingAppId() {
+ try {
+ createSampleManager("app",null, Test.GENERAL_LOCKSCREENCONFIG);
+ } catch (IllegalArgumentException ex) {
+ assertSame(ex.getMessage(), "You must specify an app ID by calling setAppId");
+ }
+ }
+
+ public void testManagerSetters() {
+ assertEquals("123456", sdlManager.getAppId());
+ assertEquals("heyApp", sdlManager.getAppName());
+ assertEquals("heyApp", sdlManager.getShortAppName());
+ assertEquals(appType, sdlManager.getAppTypes());
+ assertEquals(Language.EN_US, sdlManager.getHmiLanguage());
+ assertEquals(transport, sdlManager.getTransport());
+ assertEquals(templateColorScheme, sdlManager.getDayColorScheme());
+ assertEquals(templateColorScheme, sdlManager.getNightColorScheme());
+ assertEquals(Test.GENERAL_VECTOR_STRING, sdlManager.getVrSynonyms());
+ assertEquals(Test.GENERAL_VECTOR_TTS_CHUNKS, sdlManager.getTtsChunks());
+ assertEquals(Test.GENERAL_LOCKSCREENCONFIG, sdlManager.getLockScreenConfig());
+ assertEquals(Test.GENERAL_VERSION, sdlManager.getMinimumProtocolVersion());
+ assertEquals(Test.GENERAL_VERSION, sdlManager.getMinimumRPCVersion());
+ }
+
+ public void testStartingManager(){
+ listenerCalledCounter = 0;
+
+ sdlManager.start();
+
+ // Create and force all sub managers to be ready manually. Because SdlManager will not start until all sub managers are ready.
+ // Note: SdlManager.initialize() will not be called automatically by proxy as in real life because we have mock proxy not a real one
+ sdlManager.initialize();
+
+ // Set all sub managers' states to ready
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.READY);
+
+ // Make sure the listener is called exactly once
+ assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1);
+ }
+
+ public void testManagerStates() {
+ SdlManager sdlManager = createSampleManager("test", "00000", new LockScreenConfig());
+ sdlManager.initialize();
+
+
+ // Case 1-A:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getLockScreenConfig().setEnabled(true);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.READY, sdlManager.getState());
+
+
+ // Case 1-B:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getLockScreenConfig().setEnabled(false);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.READY, sdlManager.getState());
+
+
+ // Case 2-A:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getLockScreenConfig().setEnabled(true);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.ERROR, sdlManager.getState());
+
+
+ // Case 1-B:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getLockScreenConfig().setEnabled(false);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.ERROR, sdlManager.getState());
+
+
+ // Case 3-A:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.getLockScreenConfig().setEnabled(true);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.LIMITED);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.SETTING_UP, sdlManager.getState());
+
+
+ // Case 3-B:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.getLockScreenConfig().setEnabled(false);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.SETTING_UP, sdlManager.getState());
+
+
+ // Case 4-A:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getLockScreenConfig().setEnabled(true);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.LIMITED, sdlManager.getState());
+
+
+ // Case 4-B:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getLockScreenConfig().setEnabled(false);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.LIMITED, sdlManager.getState());
+
+
+ // Case 5-A:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.LIMITED);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getLockScreenConfig().setEnabled(true);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.READY);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.LIMITED, sdlManager.getState());
+
+
+ // Case 5-B:
+ sdlManager.getPermissionManager().transitionToState(BaseSubManager.READY);
+ sdlManager.getFileManager().transitionToState(BaseSubManager.LIMITED);
+ sdlManager.getScreenManager().transitionToState(BaseSubManager.ERROR);
+ sdlManager.getLockScreenConfig().setEnabled(false);
+ sdlManager.getLockScreenManager().transitionToState(BaseSubManager.SETTING_UP);
+ sdlManager.checkState();
+ assertEquals(BaseSubManager.LIMITED, sdlManager.getState());
+ }
+
+ public void testSendRPC(){
+ listenerCalledCounter = 0;
+
+ // When sdlProxyBase.sendRPCRequest() is called, create a fake success response
+ Answer<Void> answer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ RPCRequest request = (RPCRequest) args[0];
+ RPCResponse response = new RPCResponse(FunctionID.GET_VEHICLE_DATA.toString());
+ response.setSuccess(true);
+ request.getOnRPCResponseListener().onResponse(0, response);
+ return null;
+ }
+ };
+ try {
+ doAnswer(answer).when(sdlProxyBase).sendRPC(any(RPCMessage.class));
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+
+
+ // Test send RPC request
+ final GetVehicleData request = new GetVehicleData();
+ request.setGps(true);
+ request.setOnRPCResponseListener(new OnRPCResponseListener() {
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {
+ assertTrue(response.getSuccess());
+ listenerCalledCounter++;
+ }
+ });
+
+ sdlManager.sendRPC(request);
+
+ // Make sure the listener is called exactly once
+ assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1);
+ }
+
+ public void testSendRPCs(){
+ testSendMultipleRPCs(false);
+ }
+
+ public void testSendSequentialRPCs(){
+ testSendMultipleRPCs(true);
+ }
+
+ private void testSendMultipleRPCs(boolean sequentialSend){
+ listenerCalledCounter = 0;
+
+ // When sdlProxyBase.sendRPCRequests() is called, call listener.onFinished() to fake the response
+ final Answer<Void> answer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ OnMultipleRequestListener listener = (OnMultipleRequestListener) args[1];
+ listener.onFinished();
+ return null;
+ }
+ };
+ try {
+ if (sequentialSend){
+ doAnswer(answer).when(sdlProxyBase).sendSequentialRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ } else {
+ doAnswer(answer).when(sdlProxyBase).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+ }
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+
+
+ // Test send RPC requests
+ List<RPCMessage> rpcsList = Arrays.asList(new GetVehicleData(), new Show(), new OnAppServiceData(), new GetAppServiceDataResponse());
+ OnMultipleRequestListener onMultipleRequestListener = new OnMultipleRequestListener() {
+ @Override
+ public void onUpdate(int remainingRequests) { }
+
+ @Override
+ public void onFinished() {
+ listenerCalledCounter++;
+ }
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {}
+
+ @Override
+ public void onResponse(int correlationId, RPCResponse response) {}
+ };
+ if (sequentialSend) {
+ sdlManager.sendSequentialRPCs(rpcsList, onMultipleRequestListener);
+ } else {
+ sdlManager.sendRPCs(rpcsList, onMultipleRequestListener);
+ }
+
+
+ // Make sure the listener is called exactly once
+ assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1);
+ }
+
+}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java
new file mode 100644
index 000000000..35c57a4c3
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java
@@ -0,0 +1,681 @@
+package com.smartdevicelink.managers.audio;
+
+import android.content.Context;
+import android.media.AudioFormat;
+import android.media.MediaFormat;
+import android.media.MediaPlayer;
+import android.os.Build;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+
+import com.smartdevicelink.SdlConnection.SdlSession;
+import com.smartdevicelink.managers.CompletionListener;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType;
+import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
+import com.smartdevicelink.proxy.rpc.AudioPassThruCapabilities;
+import com.smartdevicelink.proxy.rpc.enums.AudioType;
+import com.smartdevicelink.proxy.rpc.enums.BitsPerSample;
+import com.smartdevicelink.proxy.rpc.enums.SamplingRate;
+import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
+
+import junit.framework.TestCase;
+
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+public class AudioStreamManagerTest extends TestCase {
+ public static final String TAG = AudioStreamManagerTest.class.getSimpleName();
+ private Context mContext;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mContext = InstrumentationRegistry.getContext();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ mContext = null;
+ }
+
+ public void testCreatingAudioStreamManager() {
+ ISdl internalInterface = mock(ISdl.class);
+ AudioPassThruCapabilities audioCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ doReturn(true).when(internalInterface).isConnected();
+ doReturn(audioCapabilities).when(internalInterface).getCapability(SystemCapabilityType.PCM_STREAMING);
+
+ new AudioStreamManager(internalInterface, mContext);
+ }
+
+ public void testStartAudioStreamManager() {
+ final SdlSession mockSession = mock(SdlSession.class);
+
+ Answer<Void> audioServiceAnswer = new Answer<Void>() {
+ ISdlServiceListener serviceListener = null;
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArguments();
+
+ switch (method.getName()) {
+ case "addServiceListener":
+ // parameters (SessionType serviceType, ISdlServiceListener sdlServiceListener);
+ SessionType sessionType = (SessionType) args[0];
+ assertEquals(sessionType, SessionType.PCM);
+ serviceListener = (ISdlServiceListener) args[1];
+ break;
+ case "startAudioService":
+ // parameters (boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params);
+ Boolean encrypted = (Boolean) args[0];
+ serviceListener.onServiceStarted(mockSession, SessionType.PCM, encrypted);
+ break;
+ case "stopAudioService":
+ // parameters ()
+ serviceListener.onServiceEnded(mockSession, SessionType.PCM);
+ break;
+ }
+
+ return null;
+ }
+ };
+
+ ISdl internalInterface = mock(ISdl.class);
+ AudioPassThruCapabilities audioCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ doReturn(true).when(internalInterface).isConnected();
+ doReturn(audioCapabilities).when(internalInterface).getCapability(SystemCapabilityType.PCM_STREAMING);
+ doAnswer(audioServiceAnswer).when(internalInterface).addServiceListener(any(SessionType.class), any(ISdlServiceListener.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).startAudioService(any(Boolean.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).stopAudioService();
+
+ CompletionListener completionListener = new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertEquals(true, success);
+ }
+ };
+
+ CompletionListener mockListener = spy(completionListener);
+ AudioStreamManager manager = new AudioStreamManager(internalInterface, mContext);
+
+ manager.startAudioStream(false, mockListener);
+ manager.stopAudioStream(mockListener);
+ verify(mockListener, timeout(10000).times(2)).onComplete(any(Boolean.class));
+ }
+
+ public void testWithSquareSampleAudio16BitAnd8KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd16KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd22KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd44KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd8KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd16KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd22KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd44KhzApi16() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd8KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd16KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd22KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio16BitAnd44KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.SIGNED_16_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd8KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd16KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd22KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ public void testWithSquareSampleAudio8BitAnd44KhzApi21() throws Exception {
+ setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21);
+ AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._8_BIT, AudioType.PCM);
+ runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities);
+ }
+
+ private int testFullAudioManagerDecodeFlowCorrectCounter = 0;
+ private int testFullAudioManagerDecodeFlowWrongCounter = 0;
+ private void runFullAudioManagerDecodeFlowWithSquareSampleAudio(final int sampleRate, final @SampleType int sampleType, final AudioPassThruCapabilities audioCapabilities) {
+ testFullAudioManagerDecodeFlowCorrectCounter = 0;
+ testFullAudioManagerDecodeFlowWrongCounter = 0;
+
+ IAudioStreamListener audioStreamListener = new IAudioStreamListener() {
+ @Override
+ public void sendAudio(byte[] data, int offset, int length, long presentationTimeUs) throws ArrayIndexOutOfBoundsException {
+ ByteBuffer buffer = ByteBuffer.wrap(data, offset, length);
+ this.sendAudio(buffer, presentationTimeUs);
+ }
+
+ @Override
+ public void sendAudio(ByteBuffer data, long presentationTimeUs) {
+ SampleBuffer samples = SampleBuffer.wrap(data, sampleType, presentationTimeUs);
+ double timeUs = presentationTimeUs;
+ double sampleDurationUs = 1000000.0 / sampleRate;
+
+ for (int i = 0; i < samples.limit(); ++i) {
+ double sample = samples.get(i);
+ double edge = timeUs % 4000.0;
+
+ if (edge > 2000.0) {
+ // swap sample as it's negative expected
+ sample = sample * -1.0;
+ }
+
+ edge = edge % 2000.0;
+
+ // at the edge of a wave the sample can be lower than 0.7
+ if ((sample > 0.7 && sample < 0.95) || (edge < sampleDurationUs || (2000.0 - sampleDurationUs) < edge)) {
+ testFullAudioManagerDecodeFlowCorrectCounter++;
+ } else {
+ testFullAudioManagerDecodeFlowWrongCounter++;
+ }
+
+ timeUs += sampleDurationUs;
+ }
+ }
+ };
+
+ final SdlSession mockSession = mock(SdlSession.class);
+ doReturn(audioStreamListener).when(mockSession).startAudioStream();
+
+ Answer<Void> audioServiceAnswer = new Answer<Void>() {
+ ISdlServiceListener serviceListener = null;
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArguments();
+
+ switch (method.getName()) {
+ case "addServiceListener":
+ // (SessionType serviceType, ISdlServiceListener sdlServiceListener);
+ SessionType sessionType = (SessionType) args[0];
+ assertEquals(sessionType, SessionType.PCM);
+
+ serviceListener = (ISdlServiceListener) args[1];
+ break;
+ case "startAudioService":
+ //(boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params);
+ Boolean encrypted = (Boolean) args[0];
+ serviceListener.onServiceStarted(mockSession, SessionType.PCM, encrypted);
+ break;
+ case "stopAudioService":
+ // parameters ()
+ serviceListener.onServiceEnded(mockSession, SessionType.PCM);
+ break;
+ }
+
+ return null;
+ }
+ };
+
+ ISdl internalInterface = mock(ISdl.class);
+ doReturn(true).when(internalInterface).isConnected();
+ doReturn(audioCapabilities).when(internalInterface).getCapability(any(SystemCapabilityType.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).addServiceListener(any(SessionType.class), any(ISdlServiceListener.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).startAudioService(any(Boolean.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).stopAudioService();
+
+ CompletionListener fileCompletionListener = new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertEquals(true, success);
+
+ // not more than 2.5 percent samples must be wrong
+ double relation = 100.0 * (double)testFullAudioManagerDecodeFlowWrongCounter / (double)testFullAudioManagerDecodeFlowCorrectCounter;
+ Log.v(TAG, "Validating number of correct samples (" + Math.round(relation) + "%)");
+ if (relation > 2.5) {
+ fail("Validating raw audio failed. " + Math.round(relation) + " % wrong samples detected. Correct: " + testFullAudioManagerDecodeFlowCorrectCounter + ", Wrong: " + testFullAudioManagerDecodeFlowWrongCounter);
+ }
+ }
+ };
+
+ final CompletionListener mockFileListener = spy(fileCompletionListener);
+
+ final AudioStreamManager manager = new AudioStreamManager(internalInterface, mContext);
+ manager.startAudioStream(false, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertEquals(true, success);
+
+ manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener);
+ }
+ });
+
+ verify(mockFileListener, timeout(10000)).onComplete(any(Boolean.class));
+ }
+
+ public void testSampleAtTargetTimeReturnNull() {
+ BaseAudioDecoder mockDecoder = mock(BaseAudioDecoder.class, Mockito.CALLS_REAL_METHODS);
+ Method sampleAtTargetMethod = getSampleAtTargetMethod();
+ SampleBuffer sample = SampleBuffer.allocate(1, SampleType.SIGNED_16_BIT, ByteOrder.LITTLE_ENDIAN, 1);
+ Double result;
+ try {
+ result = (Double) sampleAtTargetMethod.invoke(mockDecoder, 1.0, sample, 1, 3, 2);
+ assertNull(result);
+ result = (Double) sampleAtTargetMethod.invoke(mockDecoder, 1.0, sample, 5, 3, 1);
+ assertNull(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ public void testSampleAtTargetTimeReturnLastOutputSample() {
+ BaseAudioDecoder mockDecoder = mock(BaseAudioDecoder.class, Mockito.CALLS_REAL_METHODS);
+ Method sampleAtTargetMethod = getSampleAtTargetMethod();
+ SampleBuffer sample = SampleBuffer.allocate(1, SampleType.SIGNED_16_BIT, ByteOrder.LITTLE_ENDIAN, 1);
+ Double result;
+ Double lastOutputSample = 15.0;
+ try {
+ result = (Double) sampleAtTargetMethod.invoke(mockDecoder, lastOutputSample, sample, 6, 1, 5);
+ assertTrue(result.doubleValue() == lastOutputSample);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ public void testSampleAtTargetTimeReturnOutputSampleGet() {
+ BaseAudioDecoder mockDecoder = mock(BaseAudioDecoder.class, Mockito.CALLS_REAL_METHODS);
+ Method sampleAtTargetMethod = getSampleAtTargetMethod();
+ SampleBuffer sample = SampleBuffer.allocate(10, SampleType.SIGNED_16_BIT, ByteOrder.LITTLE_ENDIAN, 1);
+ Double result;
+ try {
+ result = (Double) sampleAtTargetMethod.invoke(mockDecoder, 1.0, sample, 1, 1, 2);
+ assertTrue(result == sample.get(1));
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ public void testSampleAtTargetTime() {
+ BaseAudioDecoder mockDecoder = mock(BaseAudioDecoder.class, Mockito.CALLS_REAL_METHODS);
+ Method sampleAtTargetMethod = getSampleAtTargetMethod();
+ SampleBuffer sample = SampleBuffer.allocate(10, SampleType.SIGNED_16_BIT, ByteOrder.LITTLE_ENDIAN, 1);
+ Double result;
+ try {
+ result = (Double) sampleAtTargetMethod.invoke(mockDecoder, 1.0, sample, 1, 3, 2);
+ assertNotNull(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ public void testOutputFormatChanged() {
+ BaseAudioDecoder mockDecoder = mock(BaseAudioDecoder.class, Mockito.CALLS_REAL_METHODS);
+
+ try {
+ Field outputChannelCountField = BaseAudioDecoder.class.getDeclaredField("outputChannelCount");
+ Field outputSampleRateField = BaseAudioDecoder.class.getDeclaredField("outputSampleRate");
+ Field outputSampleTypeField = BaseAudioDecoder.class.getDeclaredField("outputSampleType");
+
+ outputChannelCountField.setAccessible(true);
+ outputSampleRateField.setAccessible(true);
+ outputSampleTypeField.setAccessible(true);
+
+ // channel count, sample rate, sample type
+ int key_channel_count = 0, key_sample_rate = 1, key_sample_type = 2, key_sample_type_result = 3;
+ int[][] tests = new int[][] {
+ { 47, 42000, AudioFormat.ENCODING_PCM_8BIT, SampleType.UNSIGNED_8_BIT },
+ { 2, 16000, AudioFormat.ENCODING_PCM_16BIT, SampleType.SIGNED_16_BIT },
+ { 1, 22050, AudioFormat.ENCODING_PCM_FLOAT, SampleType.FLOAT },
+ { 3, 48000, AudioFormat.ENCODING_INVALID, SampleType.SIGNED_16_BIT },
+ };
+
+ for (int[] test : tests) {
+ int channel_count = test[key_channel_count];
+ int sample_rate = test[key_sample_rate];
+ int sample_type = test[key_sample_type];
+ int sample_type_result = test[key_sample_type_result];
+
+ MediaFormat format = new MediaFormat();
+
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, channel_count);
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sample_rate);
+ format.setInteger(MediaFormat.KEY_PCM_ENCODING, sample_type);
+
+ // in case the phone version is old the method does not take sample type into account but
+ // always expected 16 bit. See https://developer.android.com/reference/android/media/MediaFormat.html#KEY_PCM_ENCODING
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N) {
+ sample_type_result = SampleType.SIGNED_16_BIT;
+ }
+
+ mockDecoder.onOutputFormatChanged(format);
+
+ int output_channel_count = outputChannelCountField.getInt(mockDecoder);
+ int output_sample_rate = outputSampleRateField.getInt(mockDecoder);
+ int output_sample_type = outputSampleTypeField.getInt(mockDecoder);
+
+ // changing from assertEquals to if and fail so travis gives better results
+
+ if (channel_count != output_channel_count) {
+ fail("AssertEqualsFailed: channel_count == output_channel_count (" + channel_count + " == " + output_channel_count + ")");
+ }
+
+ if (sample_rate != output_sample_rate) {
+ fail("AssertEqualsFailed: sample_rate == output_sample_rate (" + sample_rate + " == " + output_sample_rate + ")");
+ }
+
+ if (sample_type_result != output_sample_type) {
+ fail("Assert: sample_type_result == output_sample_type (" + sample_type_result + " == " + output_sample_type + ")");
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ public void testPlayAudioFileForManualTest() throws IOException {
+ AudioPassThruCapabilities audioCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM);
+ final int sampleType = SampleType.SIGNED_16_BIT;
+ final int sampleRate = 16000;
+
+ final File outputFile = new File(mContext.getCacheDir(), "test_audio_file.wav");
+ assertNotNull((outputFile));
+ final FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
+ assertNotNull(fileOutputStream);
+ writeWaveHeader(fileOutputStream, sampleRate, sampleType << 3);
+
+ IAudioStreamListener audioStreamListener = new IAudioStreamListener() {
+ long audioLength = 0;
+
+ @Override
+ public void sendAudio(byte[] data, int offset, int length, long presentationTimeUs) throws ArrayIndexOutOfBoundsException {
+ ByteBuffer buffer = ByteBuffer.wrap(data, offset, length);
+ this.sendAudio(buffer, presentationTimeUs);
+ }
+
+ @Override
+ public void sendAudio(ByteBuffer data, long presentationTimeUs) {
+ try {
+ long length = data.limit();
+ byte[] d = data.array();
+ fileOutputStream.write(d, 0, (int) length);
+
+ audioLength += length;
+ RandomAccessFile raf = new RandomAccessFile(outputFile, "rw");
+ updateWaveHeaderLength(raf, audioLength);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ final SdlSession mockSession = mock(SdlSession.class);
+ doReturn(audioStreamListener).when(mockSession).startAudioStream();
+
+ Answer<Void> audioServiceAnswer = new Answer<Void>() {
+ ISdlServiceListener serviceListener = null;
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArguments();
+
+ switch (method.getName()) {
+ case "addServiceListener":
+ // (SessionType serviceType, ISdlServiceListener sdlServiceListener);
+ SessionType sessionType = (SessionType) args[0];
+ assertEquals(sessionType, SessionType.PCM);
+
+ serviceListener = (ISdlServiceListener) args[1];
+ break;
+ case "startAudioService":
+ //(boolean encrypted, AudioStreamingCodec codec, AudioStreamingParams params);
+ Boolean encrypted = (Boolean) args[0];
+ serviceListener.onServiceStarted(mockSession, SessionType.PCM, encrypted);
+ break;
+ case "stopAudioService":
+ // parameters ()
+ serviceListener.onServiceEnded(mockSession, SessionType.PCM);
+ break;
+ }
+
+ return null;
+ }
+ };
+
+ ISdl internalInterface = mock(ISdl.class);
+ doReturn(true).when(internalInterface).isConnected();
+ doReturn(audioCapabilities).when(internalInterface).getCapability(any(SystemCapabilityType.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).addServiceListener(any(SessionType.class), any(ISdlServiceListener.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).startAudioService(any(Boolean.class));
+ doAnswer(audioServiceAnswer).when(internalInterface).stopAudioService();
+
+ final MediaPlayer.OnCompletionListener mockPlayerCompletionListener = mock(MediaPlayer.OnCompletionListener.class);
+ final MediaPlayer player = new MediaPlayer();
+ player.setOnCompletionListener(mockPlayerCompletionListener);
+
+ CompletionListener fileCompletionListener = new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ try {
+ fileOutputStream.flush();
+ fileOutputStream.close();
+
+ player.setDataSource(outputFile.getPath());
+ player.prepare();
+ player.start();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ final CompletionListener mockFileListener = spy(fileCompletionListener);
+
+ final AudioStreamManager manager = new AudioStreamManager(internalInterface, mContext);
+ manager.startAudioStream(false, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertEquals(true, success);
+
+ manager.pushResource(com.smartdevicelink.test.R.raw.test_audio_square_250hz_80amp_1s, mockFileListener);
+ }
+ });
+
+ verify(mockFileListener, timeout(10000)).onComplete(any(Boolean.class));
+ verify(mockPlayerCompletionListener, timeout(10000)).onCompletion(any(MediaPlayer.class));
+ }
+
+ private Method getSampleAtTargetMethod() {
+ Method method = null;
+ try {
+ method = BaseAudioDecoder.class.getDeclaredMethod("sampleAtTargetTime",
+ double.class, SampleBuffer.class, double.class, double.class, double.class);
+ method.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ fail();
+ }
+ return method;
+ }
+
+ private void setFinalStatic(Field field, Object newValue) throws Exception {
+ field.setAccessible(true);
+ field.set(null, newValue);
+ }
+
+ private void writeWaveHeader(OutputStream stream, long samplerate, long bitspersample) throws IOException {
+ byte[] header = new byte[44];
+ // the data header is 36 bytes large
+ long datalength = 36;
+ long audiolength = 0;
+ long format = 1; // 1 = PCM
+ long channels = 1;
+ long blockalign = (channels * bitspersample) >> 3;
+ long byterate = (samplerate * channels * bitspersample) >> 3;
+
+ // RIFF header.
+ header[0] = 'R';
+ header[1] = 'I';
+ header[2] = 'F';
+ header[3] = 'F';
+ // Total data length (UInt32).
+ header[4] = (byte)((datalength) & 0xff);
+ header[5] = (byte)((datalength >> 8) & 0xff);
+ header[6] = (byte)((datalength >> 16) & 0xff);
+ header[7] = (byte)((datalength >> 24) & 0xff);
+ // WAVE header.
+ header[8] = 'W';
+ header[9] = 'A';
+ header[10] = 'V';
+ header[11] = 'E';
+ // Format (fmt) header.
+ header[12] = 'f';
+ header[13] = 'm';
+ header[14] = 't';
+ header[15] = ' ';
+ // Format header size (UInt32).
+ header[16] = 16;
+ header[17] = 0;
+ header[18] = 0;
+ header[19] = 0;
+ // Format type (UInt16). Set 1 for PCM.
+ header[20] = (byte)((format) & 0xff);
+ header[21] = (byte)((format >> 8) & 0xff);
+ // Channels
+ header[22] = (byte)((channels) & 0xff);
+ header[23] = (byte)((channels >> 8) & 0xff);
+ // Sample rate (UInt32).
+ header[24] = (byte)((samplerate) & 0xff);
+ header[25] = (byte)((samplerate >> 8) & 0xff);
+ header[26] = (byte)((samplerate >> 16) & 0xff);
+ header[27] = (byte)((samplerate >> 24) & 0xff);
+ // Byte rate (UInt32).
+ header[28] = (byte)((byterate) & 0xff);
+ header[29] = (byte)((byterate >> 8) & 0xff);
+ header[30] = (byte)((byterate >> 16) & 0xff);
+ header[31] = (byte)((byterate >> 24) & 0xff);
+ // Block alignment (UInt16).
+ header[32] = (byte)((blockalign) & 0xff);
+ header[33] = (byte)((blockalign >> 8) & 0xff);
+ // Bits per sample (UInt16).
+ header[34] = (byte)((bitspersample) & 0xff);
+ header[35] = (byte)((bitspersample >> 8) & 0xff);
+ // Data header
+ header[36] = 'd';
+ header[37] = 'a';
+ header[38] = 't';
+ header[39] = 'a';
+ // Total audio length (UInt32).
+ header[40] = (byte)((audiolength) & 0xff);
+ header[41] = (byte)((audiolength >> 8) & 0xff);
+ header[42] = (byte)((audiolength >> 16) & 0xff);
+ header[43] = (byte)((audiolength >> 24) & 0xff);
+
+ stream.write(header, 0, header.length);
+ }
+
+ /** Updates the data length and audio length of an existing RIFF/WAVE header in the file pointed by the RandomAccessFile object. */
+ private void updateWaveHeaderLength(RandomAccessFile stream, long audiolength) throws IOException {
+ // the data header is 36 bytes large
+ long datalength = 36 + audiolength;
+
+ // Seek from the beginning to data length
+ stream.seek(4);
+ // Overwrite total data length
+ stream.write((int)((datalength) & 0xff));
+ stream.write((int)((datalength >> 8) & 0xff));
+ stream.write((int)((datalength >> 16) & 0xff));
+ stream.write((int)((datalength >> 24) & 0xff));
+ // Seek from the end of data length to audio length
+ stream.seek(40);
+ // overwrite total audio length
+ stream.write((int)((audiolength) & 0xff));
+ stream.write((int)((audiolength >> 8) & 0xff));
+ stream.write((int)((audiolength >> 16) & 0xff));
+ stream.write((int)((audiolength >> 24) & 0xff));
+ }
+}
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
new file mode 100644
index 000000000..b4e27f205
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/file/FileManagerTests.java
@@ -0,0 +1,507 @@
+package com.smartdevicelink.managers.file;
+
+import android.content.Context;
+import android.net.Uri;
+
+import com.smartdevicelink.AndroidTestCase2;
+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.RPCRequest;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.ListFiles;
+import com.smartdevicelink.proxy.rpc.ListFilesResponse;
+import com.smartdevicelink.proxy.rpc.PutFile;
+import com.smartdevicelink.proxy.rpc.PutFileResponse;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.Result;
+import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
+import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.Assert;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link FileManager}
+ */
+public class FileManagerTests extends AndroidTestCase2 {
+ public static final String TAG = "FileManagerTests";
+ private FileManager fileManager;
+ private Context mTestContext;
+ private SdlFile validFile;
+
+ // SETUP / HELPERS
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+ mTestContext = this.getContext();
+ validFile = new SdlFile();
+ validFile.setName(Test.GENERAL_STRING);
+ validFile.setFileData(Test.GENERAL_BYTE_ARRAY);
+ validFile.setPersistent(false);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private Answer<Void> onListFilesSuccess = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ RPCRequest message = (RPCRequest) args[0];
+ if(message instanceof ListFiles){
+ 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);
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onListFilesFailure = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ RPCRequest message = (RPCRequest) args[0];
+ if(message instanceof ListFiles){
+ int correlationId = message.getCorrelationID();
+ ListFilesResponse listFilesResponse = new ListFilesResponse();
+ listFilesResponse.setSuccess(false);
+ message.getOnRPCResponseListener().onResponse(correlationId, listFilesResponse);
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onPutFileSuccess = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ RPCRequest message = (RPCRequest) args[0];
+ if(message instanceof PutFile){
+ int correlationId = message.getCorrelationID();
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(true);
+ message.getOnRPCResponseListener().onResponse(correlationId, putFileResponse);
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onPutFileFailure = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ RPCRequest message = (RPCRequest) args[0];
+ if(message instanceof PutFile){
+ int correlationId = message.getCorrelationID();
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(false);
+ message.getOnRPCResponseListener().onResponse(correlationId, putFileResponse);
+ }
+ return null;
+ }
+ };
+
+ private Answer<Void> onSendRequestsSuccess = 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){
+ int correlationId = message.getCorrelationID();
+ listener.addCorrelationId(correlationId);
+ PutFileResponse putFileResponse = new PutFileResponse();
+ putFileResponse.setSuccess(true);
+ listener.onResponse(correlationId, putFileResponse);
+ }
+ }
+ return null;
+ }
+ };
+
+ // TESTS
+
+ public void testInitializationSuccess(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ Assert.assertEquals(fileManager.getState(), BaseSubManager.READY);
+ assertEquals(fileManager.getRemoteFileNames(), Test.GENERAL_STRING_LIST);
+ }
+ });
+ }
+
+ public void testInitializationFailure(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesFailure).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertFalse(success);
+ assertEquals(fileManager.getState(), BaseSubManager.ERROR);
+ }
+ });
+ }
+
+ public void testFileUploadSuccess(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onPutFileSuccess).when(internalInterface).sendRPCRequest(any(PutFile.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ 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);
+ assertTrue(fileManager.getRemoteFileNames().contains(validFile.getName()));
+ assertTrue(fileManager.hasUploadedFile(validFile));
+ }
+ });
+ }
+ });
+ }
+
+ public void testFileUploadFailure(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onPutFileFailure).when(internalInterface).sendRPCRequest(any(PutFile.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ 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);
+ assertFalse(fileManager.getRemoteFileNames().contains(validFile.getName()));
+ assertFalse(fileManager.hasUploadedFile(validFile));
+ }
+ });
+ }
+ });
+ }
+
+ public void testFileUploadForStaticIcon(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ SdlArtwork artwork = new SdlArtwork(StaticIconName.ALBUM);
+ fileManager.uploadFile(artwork, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ }
+ });
+ }
+ });
+ }
+
+ public void testInvalidSdlFileInput(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ SdlFile sdlFile = new SdlFile();
+ // Don't set name
+ sdlFile.setFileData(Test.GENERAL_BYTE_ARRAY);
+ checkForUploadFailure(fileManager, sdlFile);
+
+ sdlFile = new SdlFile();
+ sdlFile.setName(Test.GENERAL_STRING);
+ // Don't set data
+ checkForUploadFailure(fileManager, sdlFile);
+
+ sdlFile = new SdlFile();
+ sdlFile.setName(Test.GENERAL_STRING);
+ // Give an invalid resource ID
+ sdlFile.setResourceId(Test.GENERAL_INT);
+ checkForUploadFailure(fileManager, sdlFile);
+
+ sdlFile = new SdlFile();
+ sdlFile.setName(Test.GENERAL_STRING);
+ // Set invalid Uri
+ Uri testUri = Uri.parse("http://www.google.com");
+ sdlFile.setUri(testUri);
+ checkForUploadFailure(fileManager, sdlFile);
+ }
+ });
+ }
+
+ private void checkForUploadFailure(FileManager fileManager, SdlFile sdlFile){
+ boolean error = false;
+
+ try {
+ fileManager.uploadFile(sdlFile, new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {}
+ });
+ }catch (IllegalArgumentException e){
+ error = true;
+ }
+
+ assertTrue(error);
+ }
+
+ public void testInvalidSdlArtworkInput(){
+ SdlArtwork sdlArtwork = new SdlArtwork();
+ // Set invalid type
+ for(FileType fileType : FileType.values()){
+ boolean shouldError = true, didError = false;
+ if(fileType.equals(FileType.GRAPHIC_BMP) || fileType.equals(FileType.GRAPHIC_PNG)
+ || fileType.equals(FileType.GRAPHIC_JPEG)){
+ shouldError = false;
+ }
+ try{
+ sdlArtwork.setType(fileType);
+ }catch(IllegalArgumentException e){
+ didError = true;
+ }
+ assertEquals(shouldError, didError);
+ }
+ }
+
+ public void testMultipleFileUploadThenDeleteSuccess(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.class));
+ doAnswer(onSendRequestsSuccess).when(internalInterface).sendRequests(any(List.class), any(OnMultipleRequestListener.class));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ 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);
+
+ sdlFile = new SdlFile();
+ sdlFile.setName("file" + fileNum++);
+ sdlFile.setResourceId(com.smartdevicelink.test.R.drawable.ic_sdl);
+ filesToUpload.add(sdlFile);
+
+ 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()));
+ }
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+ public void testMultipleFileUploadPartialFailure(){
+ final String failureReason = "No space available";
+
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(any(ListFiles.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));
+
+ 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 = new SdlFile();
+ sdlFile.setName(baseFileName + fileNum++);
+ sdlFile.setResourceId(com.smartdevicelink.test.R.drawable.ic_sdl);
+ filesToUpload.add(sdlFile);
+
+ sdlFile = new SdlFile();
+ sdlFile.setName(baseFileName + fileNum++);
+ sdlFile.setFileData(Test.GENERAL_BYTE_ARRAY);
+ sdlFile.setPersistent(true);
+ sdlFile.setType(FileType.BINARY);
+ filesToUpload.add(sdlFile);
+
+ 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()));
+ }
+ }
+ }
+ });
+ }
+ });
+ }
+
+ 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));
+
+ final FileManager fileManager = new FileManager(internalInterface, mTestContext);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ int fileNum = 1;
+ final List<SdlArtwork> artworkToUpload = new ArrayList<>();
+ SdlArtwork sdlArtwork = new SdlArtwork();
+ sdlArtwork.setName("art" + fileNum++);
+ Uri uri = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl");
+ sdlArtwork.setUri(uri);
+ sdlArtwork.setType(FileType.GRAPHIC_PNG);
+ artworkToUpload.add(sdlArtwork);
+
+ sdlArtwork = new SdlArtwork();
+ sdlArtwork.setName("art" + fileNum++);
+ uri = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/sdl_tray_icon");
+ sdlArtwork.setUri(uri);
+ sdlArtwork.setType(FileType.GRAPHIC_PNG);
+ artworkToUpload.add(sdlArtwork);
+
+ fileManager.uploadFiles(artworkToUpload,
+ new MultipleFileCompletionListener() {
+ @Override
+ public void onComplete(Map<String, String> errors) {
+ assertNull(errors);
+ List < String > uploadedFileNames = fileManager.getRemoteFileNames();
+ for(SdlArtwork artwork : artworkToUpload){
+ assertTrue(uploadedFileNames.contains(artwork.getName()));
+ }
+ }
+ });
+ }
+ });
+ }
+
+ public void testPersistentFileUploaded(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ doAnswer(onListFilesSuccess).when(internalInterface).sendRPCRequest(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);
+ fileManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(fileManager.hasUploadedFile(file));
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenConfigTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenConfigTests.java
new file mode 100644
index 000000000..c2d4066ce
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenConfigTests.java
@@ -0,0 +1,45 @@
+package com.smartdevicelink.managers.lockscreen;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.test.Test;
+
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link com.smartdevicelink.managers.lockscreen.LockScreenConfig}
+ *
+ * We currently do not need to test null values, as each currently is a primitive
+ */
+public class LockScreenConfigTests extends AndroidTestCase2 {
+
+ private LockScreenConfig lockScreenConfig;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // set info for all the setters
+ lockScreenConfig = new LockScreenConfig();
+ lockScreenConfig.setCustomView(Test.GENERAL_INT);
+ lockScreenConfig.setAppIcon(Test.GENERAL_INT);
+ lockScreenConfig.setBackgroundColor(Test.GENERAL_INT);
+ lockScreenConfig.showDeviceLogo(true);
+ lockScreenConfig.setEnabled(true);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testLockScreenConfig() {
+
+ // get the info and make sure its correct
+ assertEquals(Test.GENERAL_INT, lockScreenConfig.getCustomView());
+ assertEquals(Test.GENERAL_INT, lockScreenConfig.getAppIcon());
+ assertEquals(Test.GENERAL_INT, lockScreenConfig.getBackgroundColor());
+ assertEquals(true, lockScreenConfig.isEnabled());
+ assertEquals(true, lockScreenConfig.isDeviceLogoEnabled());
+ }
+
+} \ No newline at end of file
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java
new file mode 100644
index 000000000..69e0aa898
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lockscreen/LockScreenManagerTests.java
@@ -0,0 +1,56 @@
+package com.smartdevicelink.managers.lockscreen;
+
+import android.content.Context;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.enums.LockScreenStatus;
+import com.smartdevicelink.test.Test;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link com.smartdevicelink.managers.lockscreen.LockScreenManager}
+ */
+public class LockScreenManagerTests extends AndroidTestCase2 {
+
+ private LockScreenManager lockScreenManager;
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+
+ ISdl internalInterface = mock(ISdl.class);
+
+ Context context = getContext();
+ // create config
+ LockScreenConfig lockScreenConfig = new LockScreenConfig();
+ lockScreenConfig.setCustomView(Test.GENERAL_INT);
+ lockScreenConfig.setAppIcon(Test.GENERAL_INT);
+ lockScreenConfig.setBackgroundColor(Test.GENERAL_INT);
+ lockScreenConfig.showDeviceLogo(true);
+ lockScreenConfig.setEnabled(true);
+
+ lockScreenManager = new LockScreenManager(lockScreenConfig, context, internalInterface);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testVariables() {
+ assertEquals(Test.GENERAL_INT, lockScreenManager.customView);
+ assertEquals(Test.GENERAL_INT, lockScreenManager.lockScreenIcon);
+ assertEquals(Test.GENERAL_INT, lockScreenManager.lockScreenColor);
+ assertEquals(true, lockScreenManager.deviceLogoEnabled);
+ assertEquals(true, lockScreenManager.lockScreenEnabled);
+ assertNull(lockScreenManager.deviceLogo);
+ }
+
+ public void testGetLockScreenStatus(){
+ assertEquals(LockScreenStatus.OFF, lockScreenManager.getLockScreenStatus());
+ }
+
+}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/permission/PermissionManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/permission/PermissionManagerTests.java
new file mode 100644
index 000000000..6a66a3092
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/permission/PermissionManagerTests.java
@@ -0,0 +1,203 @@
+package com.smartdevicelink.managers.permission;
+
+import android.support.annotation.NonNull;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.HMIPermissions;
+import com.smartdevicelink.proxy.rpc.OnHMIStatus;
+import com.smartdevicelink.proxy.rpc.OnPermissionsChange;
+import com.smartdevicelink.proxy.rpc.ParameterPermissions;
+import com.smartdevicelink.proxy.rpc.PermissionItem;
+import com.smartdevicelink.proxy.rpc.enums.HMILevel;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static com.smartdevicelink.managers.permission.PermissionManager.PERMISSION_GROUP_STATUS_ALLOWED;
+import static com.smartdevicelink.managers.permission.PermissionManager.PERMISSION_GROUP_STATUS_MIXED;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+public class PermissionManagerTests extends AndroidTestCase2 {
+
+ private OnRPCNotificationListener onHMIStatusListener, onPermissionsChangeListener;
+ private PermissionManager permissionManager;
+ private int listenerCalledCounter;
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Mock Isdl and its behaviour to use it for PermissionManager testing
+ ISdl internalInterface = mock(ISdl.class);
+
+
+ // When internalInterface.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, OnRPCNotificationListener) is called
+ // inside PermissionManager's constructor, then keep a reference to the OnRPCNotificationListener so we can trigger it later
+ // to emulate what Core does when it sends OnHMIStatus notification
+ Answer<Void> onHMIStatusAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ onHMIStatusListener = (OnRPCNotificationListener) args[1];
+ return null;
+ }
+ };
+ doAnswer(onHMIStatusAnswer).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCNotificationListener.class));
+
+
+ // When internalInterface.addOnRPCNotificationListener(FunctionID.ON_PERMISSIONS_CHANGE, OnRPCNotificationListener) is called
+ // inside PermissionManager's constructor, then keep a reference to the onPermissionsChangeListener so we can trigger it later
+ // to emulate what Core does when it sends OnPermissionsChange notification
+ Answer<Void> onPermissionsChangeAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ onPermissionsChangeListener = (OnRPCNotificationListener) args[1];
+ return null;
+ }
+ };
+ doAnswer(onPermissionsChangeAnswer).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_PERMISSIONS_CHANGE), any(OnRPCNotificationListener.class));
+
+
+ // Initialize PermissionManager
+ permissionManager = new PermissionManager(internalInterface);
+ }
+
+ // Emulate what happens when Core sends OnHMIStatus notification
+ private void sendFakeCoreOnHMIStatusNotifications(HMILevel hmiLevel) {
+ if (hmiLevel != null) {
+ OnHMIStatus onHMIStatusFakeNotification = new OnHMIStatus();
+ onHMIStatusFakeNotification.setHmiLevel(hmiLevel);
+ onHMIStatusListener.onNotified(onHMIStatusFakeNotification);
+ }
+ }
+
+ // Emulate what happens when Core sends OnPermissionsChange notification
+ private void sendFakeCoreOnPermissionsChangeNotifications(List<PermissionItem> permissionItems) {
+ if (permissionItems != null) {
+ OnPermissionsChange onPermissionChangeFakeNotification = new OnPermissionsChange();
+ onPermissionChangeFakeNotification.setPermissionItem(permissionItems);
+ onPermissionsChangeListener.onNotified(onPermissionChangeFakeNotification);
+ }
+ }
+
+ // Test adding a listener to be called when ALL of the specified permissions become allowed
+ public void testListenersAllAllowed() {
+ listenerCalledCounter = 0;
+
+
+ // Test how developers can add listeners through PermissionManager
+ List<PermissionElement> permissionElements = new ArrayList<>();
+ permissionElements.add(new PermissionElement(FunctionID.SHOW, null));
+ permissionElements.add(new PermissionElement(FunctionID.GET_VEHICLE_DATA, Arrays.asList("rpm", "airbagStatus")));
+ permissionManager.addListener(permissionElements, PermissionManager.PERMISSION_GROUP_TYPE_ALL_ALLOWED, new OnPermissionChangeListener() {
+ @Override
+ public void onPermissionsChange(@NonNull Map<FunctionID, PermissionStatus> allowedPermissions, @NonNull int permissionGroupStatus) {
+ // Make sure is the actual result matches the expected one
+ assertEquals(permissionGroupStatus, PERMISSION_GROUP_STATUS_ALLOWED);
+ assertTrue(allowedPermissions.get(FunctionID.SHOW).getIsRPCAllowed());
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getIsRPCAllowed());
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("rpm"));
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("airbagStatus"));
+ listenerCalledCounter++;
+ }
+ });
+
+
+ // Emulate Core's behaviour by sending OnHMIStatus notification
+ sendFakeCoreOnHMIStatusNotifications(HMILevel.HMI_LIMITED);
+
+
+ // Emulate Core's behaviour by sending OnPermissionsChange notification
+ List<PermissionItem> permissionItems = new ArrayList<>();
+ PermissionItem permissionItem1 = new PermissionItem();
+ permissionItem1.setRpcName(FunctionID.SHOW.toString());
+ permissionItem1.setHMIPermissions(new HMIPermissions(Arrays.asList(HMILevel.HMI_BACKGROUND, HMILevel.HMI_FULL, HMILevel.HMI_LIMITED), new ArrayList<HMILevel>()));
+ permissionItem1.setParameterPermissions(new ParameterPermissions(new ArrayList<String>(), new ArrayList<String>()));
+ permissionItems.add(permissionItem1);
+ PermissionItem permissionItem2 = new PermissionItem();
+ permissionItem2.setRpcName(FunctionID.GET_VEHICLE_DATA.toString());
+ permissionItem2.setHMIPermissions(new HMIPermissions(Arrays.asList(HMILevel.HMI_BACKGROUND, HMILevel.HMI_FULL), new ArrayList<HMILevel>()));
+ permissionItem2.setParameterPermissions(new ParameterPermissions(Arrays.asList("rpm", "airbagStatus"), new ArrayList<String>()));
+ permissionItems.add(permissionItem2);
+ sendFakeCoreOnPermissionsChangeNotifications(permissionItems);
+
+
+ // Emulate Core's behaviour by sending OnHMIStatus notification
+ sendFakeCoreOnHMIStatusNotifications(HMILevel.HMI_FULL);
+
+
+ // Make sure the listener is called exactly once
+ assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 1);
+ }
+
+
+ // Test adding a listener to be called when ANY of the specified permissions become allowed
+ public void testListenersAnyAllowed() {
+ listenerCalledCounter = 0;
+
+ // Test how developers can add listeners through PermissionManager
+ List<PermissionElement> permissionElements = new ArrayList<>();
+ permissionElements.add(new PermissionElement(FunctionID.SHOW, null));
+ permissionElements.add(new PermissionElement(FunctionID.GET_VEHICLE_DATA, Arrays.asList("rpm", "airbagStatus")));
+ permissionManager.addListener(permissionElements, PermissionManager.PERMISSION_GROUP_TYPE_ANY, new OnPermissionChangeListener() {
+ @Override
+ public void onPermissionsChange(@NonNull Map<FunctionID, PermissionStatus> allowedPermissions, @NonNull int permissionGroupStatus) {
+ // Make sure is the actual result matches the expected one
+ if (listenerCalledCounter == 0) { // Listener called for the first time
+ assertEquals(permissionGroupStatus, PERMISSION_GROUP_STATUS_MIXED);
+ assertTrue(allowedPermissions.get(FunctionID.SHOW).getIsRPCAllowed());
+ assertTrue(!allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getIsRPCAllowed());
+ assertTrue(!allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("rpm"));
+ assertTrue(!allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("airbagStatus"));
+ } else if (listenerCalledCounter == 1) { // Listener called for the second time
+ assertEquals(permissionGroupStatus, PERMISSION_GROUP_STATUS_ALLOWED);
+ assertTrue(allowedPermissions.get(FunctionID.SHOW).getIsRPCAllowed());
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getIsRPCAllowed());
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("rpm"));
+ assertTrue(allowedPermissions.get(FunctionID.GET_VEHICLE_DATA).getAllowedParameters().get("airbagStatus"));
+ }
+ listenerCalledCounter++;
+ }
+ });
+
+
+ // Emulate Core's behaviour by sending OnHMIStatus notification
+ sendFakeCoreOnHMIStatusNotifications(HMILevel.HMI_LIMITED);
+
+
+ // Emulate Core's behaviour by sending OnPermissionsChange notification
+ List<PermissionItem> permissionItems = new ArrayList<>();
+ PermissionItem permissionItem1 = new PermissionItem();
+ permissionItem1.setRpcName(FunctionID.SHOW.toString());
+ permissionItem1.setHMIPermissions(new HMIPermissions(Arrays.asList(HMILevel.HMI_BACKGROUND, HMILevel.HMI_FULL, HMILevel.HMI_LIMITED), new ArrayList<HMILevel>()));
+ permissionItem1.setParameterPermissions(new ParameterPermissions(new ArrayList<String>(), new ArrayList<String>()));
+ permissionItems.add(permissionItem1);
+ PermissionItem permissionItem2 = new PermissionItem();
+ permissionItem2.setRpcName(FunctionID.GET_VEHICLE_DATA.toString());
+ permissionItem2.setHMIPermissions(new HMIPermissions(Arrays.asList(HMILevel.HMI_BACKGROUND, HMILevel.HMI_FULL), new ArrayList<HMILevel>()));
+ permissionItem2.setParameterPermissions(new ParameterPermissions(Arrays.asList("rpm", "airbagStatus"), new ArrayList<String>()));
+ permissionItems.add(permissionItem2);
+ sendFakeCoreOnPermissionsChangeNotifications(permissionItems);
+
+
+ // Emulate Core's behaviour by sending OnHMIStatus notification
+ sendFakeCoreOnHMIStatusNotifications(HMILevel.HMI_FULL);
+
+
+ // Make sure the the listener is called exactly twice
+ assertEquals("Listener was not called or called more/less frequently than expected", listenerCalledCounter, 2);
+ }
+}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java
new file mode 100644
index 000000000..872e09b81
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java
@@ -0,0 +1,135 @@
+package com.smartdevicelink.managers.screen;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.managers.BaseSubManager;
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.MetadataType;
+import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link ScreenManager}
+ */
+public class ScreenManagerTests extends AndroidTestCase2 {
+ private ScreenManager screenManager;
+ private SdlArtwork testArtwork;
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
+ screenManager = new ScreenManager(internalInterface, fileManager);
+ screenManager.start(null);
+
+
+ testArtwork = new SdlArtwork("testFile", FileType.GRAPHIC_PNG, 1, false);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testInstantiation(){
+ assertNull(screenManager.getTextField1());
+ assertNull(screenManager.getTextField2());
+ assertNull(screenManager.getTextField3());
+ assertNull(screenManager.getTextField4());
+ assertNull(screenManager.getMediaTrackTextField());
+ assertNull(screenManager.getPrimaryGraphic());
+ assertNull(screenManager.getSecondaryGraphic());
+ assertEquals(screenManager.getTextAlignment(), TextAlignment.CENTERED);
+ assertNull(screenManager.getTextField1Type());
+ assertNull(screenManager.getTextField2Type());
+ assertNull(screenManager.getTextField3Type());
+ assertNull(screenManager.getTextField4Type());
+ assertTrue(screenManager.getSoftButtonObjects().isEmpty());
+ assertNull(screenManager.getSoftButtonObjectByName("test"));
+ assertNull(screenManager.getSoftButtonObjectById(1));
+ assertEquals(screenManager.getState(), BaseSubManager.READY);
+ }
+
+ public void testSetTextField() {
+ screenManager.setTextField1("It is");
+ screenManager.setTextField2("Wednesday");
+ screenManager.setTextField3("My");
+ screenManager.setTextField4("Dudes");
+ assertEquals(screenManager.getTextField1(), "It is");
+ assertEquals(screenManager.getTextField2(), "Wednesday");
+ assertEquals(screenManager.getTextField3(), "My");
+ assertEquals(screenManager.getTextField4(), "Dudes");
+ }
+
+ public void testMediaTrackTextFields() {
+ String songTitle = "Wild For The Night";
+ screenManager.setMediaTrackTextField(songTitle);
+ assertEquals(screenManager.getMediaTrackTextField(), songTitle);
+ }
+
+ public void testSetPrimaryGraphic() {
+ screenManager.setPrimaryGraphic(testArtwork);
+ assertEquals(screenManager.getPrimaryGraphic(), testArtwork);
+ }
+
+ public void testSetPrimaryGraphicWithBlankImage() {
+ screenManager.setPrimaryGraphic(null);
+ assertNotNull(screenManager.getPrimaryGraphic());
+ assertEquals(screenManager.getPrimaryGraphic().getName(), "blankArtwork");
+ }
+
+ public void testSetSecondaryGraphic() {
+ screenManager.setSecondaryGraphic(testArtwork);
+ assertEquals(screenManager.getSecondaryGraphic(), testArtwork);
+ }
+
+ public void testSetSecondaryGraphicWithBlankImage() {
+ screenManager.setSecondaryGraphic(null);
+ assertNotNull(screenManager.getSecondaryGraphic());
+ assertEquals(screenManager.getSecondaryGraphic().getName(), "blankArtwork");
+ }
+
+ public void testAlignment() {
+ screenManager.setTextAlignment(TextAlignment.LEFT_ALIGNED);
+ assertEquals(screenManager.getTextAlignment(), TextAlignment.LEFT_ALIGNED);
+ }
+
+ public void testSetTextFieldTypes() {
+ screenManager.setTextField1Type(MetadataType.MEDIA_TITLE);
+ screenManager.setTextField2Type(MetadataType.MEDIA_ALBUM);
+ screenManager.setTextField3Type(MetadataType.MEDIA_ARTIST);
+ screenManager.setTextField4Type(MetadataType.MEDIA_GENRE);
+ assertEquals(screenManager.getTextField1Type(), MetadataType.MEDIA_TITLE);
+ assertEquals(screenManager.getTextField2Type(), MetadataType.MEDIA_ALBUM);
+ assertEquals(screenManager.getTextField3Type(), MetadataType.MEDIA_ARTIST);
+ assertEquals(screenManager.getTextField4Type(), MetadataType.MEDIA_GENRE);
+ }
+
+ public void testSetSoftButtonObjects(){
+ // Create softButtonObject1
+ SoftButtonState softButtonState1 = new SoftButtonState("object1-state1", "it is", testArtwork);
+ SoftButtonState softButtonState2 = new SoftButtonState("object1-state2", "Wed", testArtwork);
+ SoftButtonObject softButtonObject1 = new SoftButtonObject("object1", Arrays.asList(softButtonState1, softButtonState2), softButtonState1.getName(),null);
+
+ // Create softButtonObject2
+ SoftButtonState softButtonState3 = new SoftButtonState("object2-state1", "my", testArtwork);
+ SoftButtonState softButtonState4 = new SoftButtonState("object2-state2", "dudes!", null);
+ SoftButtonObject softButtonObject2 = new SoftButtonObject("object2", Arrays.asList(softButtonState3, softButtonState4), softButtonState3.getName(), null);
+
+ List<SoftButtonObject> softButtonObjects = Arrays.asList(softButtonObject1, softButtonObject2);
+ screenManager.setSoftButtonObjects(Arrays.asList(softButtonObject1, softButtonObject2));
+ assertEquals(screenManager.getSoftButtonObjects(), softButtonObjects);
+ assertEquals(screenManager.getSoftButtonObjectByName("object2"), softButtonObject2);
+ assertEquals(screenManager.getSoftButtonObjectById(100), softButtonObject2);
+ }
+
+}
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
new file mode 100644
index 000000000..144057c36
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java
@@ -0,0 +1,242 @@
+package com.smartdevicelink.managers.screen;
+
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.managers.CompletionListener;
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.MultipleFileCompletionListener;
+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.OnHMIStatus;
+import com.smartdevicelink.proxy.rpc.Show;
+import com.smartdevicelink.proxy.rpc.SoftButton;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.HMILevel;
+import com.smartdevicelink.proxy.rpc.enums.ImageType;
+import com.smartdevicelink.proxy.rpc.enums.SoftButtonType;
+import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
+import com.smartdevicelink.test.Validator;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link SoftButtonManager}
+ */
+public class SoftButtonManagerTests extends AndroidTestCase2 {
+
+ private SoftButtonManager softButtonManager;
+ private boolean fileManagerUploadArtworksGotCalled;
+ private boolean internalInterfaceSendRPCRequestGotCalled;
+ private boolean softButtonMangerUpdateCompleted;
+ private SoftButtonObject softButtonObject1, softButtonObject2;
+ private SoftButtonState softButtonState1, softButtonState2, softButtonState3, softButtonState4;
+
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // When internalInterface.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, OnRPCNotificationListener) is called
+ // inside SoftButtonManager, respond with a fake HMILevel.HMI_FULL response to let the SoftButtonManager continue working.
+ ISdl internalInterface = mock(ISdl.class);
+ Answer<Void> onHMIStatusAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ OnRPCNotificationListener onHMIStatusListener = (OnRPCNotificationListener) args[1];
+ OnHMIStatus onHMIStatusFakeNotification = new OnHMIStatus();
+ onHMIStatusFakeNotification.setHmiLevel(HMILevel.HMI_FULL);
+ onHMIStatusListener.onNotified(onHMIStatusFakeNotification);
+ return null;
+ }
+ };
+ doAnswer(onHMIStatusAnswer).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCNotificationListener.class));
+
+
+ // When fileManager.uploadArtworks() is called inside the SoftButtonManager, respond with
+ // a fake onComplete() callback to let the SoftButtonManager continue working.
+ FileManager fileManager = mock(FileManager.class);
+ Answer<Void> onFileManagerUploadAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ fileManagerUploadArtworksGotCalled = true;
+ Object[] args = invocation.getArguments();
+ MultipleFileCompletionListener multipleFileCompletionListener = (MultipleFileCompletionListener) args[1];
+ multipleFileCompletionListener.onComplete(null);
+ return null;
+ }
+ };
+ doAnswer(onFileManagerUploadAnswer).when(fileManager).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class));
+
+
+ // Create softButtonManager
+ softButtonManager = new SoftButtonManager(internalInterface, fileManager);
+
+
+ // When internalInterface.sendRPCRequest() is called inside SoftButtonManager:
+ // 1) respond with a fake onResponse() callback to let the SoftButtonManager continue working
+ // 2) assert that the Show RPC values (ie: MainField1 & SoftButtons) that are created by the SoftButtonManager, match the ones that are provided by the developer
+ Answer<Void> onSendShowRPCAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ internalInterfaceSendRPCRequestGotCalled = true;
+ Object[] args = invocation.getArguments();
+ Show show = (Show) args[0];
+
+ show.getOnRPCResponseListener().onResponse(0, null);
+
+ assertEquals(show.getMainField1(), softButtonManager.getCurrentMainField1());
+ assertEquals(show.getSoftButtons().size(), softButtonManager.createSoftButtonsForCurrentState().size());
+
+ return null;
+ }
+ };
+ doAnswer(onSendShowRPCAnswer).when(internalInterface).sendRPCRequest(any(Show.class));
+
+
+ // Create soft button objects
+ softButtonState1 = new SoftButtonState("object1-state1", "o1s1", new SdlArtwork("image1", FileType.GRAPHIC_PNG, 1, true));
+ softButtonState2 = new SoftButtonState("object1-state2", "o1s2", new SdlArtwork(StaticIconName.ALBUM));
+ softButtonObject1 = new SoftButtonObject("object1", Arrays.asList(softButtonState1, softButtonState2), softButtonState1.getName(), null);
+ softButtonState3 = new SoftButtonState("object2-state1", "o2s1", null);
+ softButtonState4 = new SoftButtonState("object2-state2", "o2s2", new SdlArtwork("image3", FileType.GRAPHIC_PNG, 3, true));
+ softButtonObject2 = new SoftButtonObject("object2", Arrays.asList(softButtonState3, softButtonState4), softButtonState3.getName(), null);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testSoftButtonManagerUpdate() {
+ // Reset the boolean variables
+ fileManagerUploadArtworksGotCalled = false;
+ internalInterfaceSendRPCRequestGotCalled = false;
+ softButtonMangerUpdateCompleted = false;
+
+
+ // Test batch update
+ softButtonManager.setBatchUpdates(true);
+ List<SoftButtonObject> softButtonObjects = Arrays.asList(softButtonObject1, softButtonObject2);
+ softButtonManager.setSoftButtonObjects(Arrays.asList(softButtonObject1, softButtonObject2));
+ softButtonManager.setBatchUpdates(false);
+ softButtonManager.update(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ softButtonMangerUpdateCompleted = true;
+ }
+ });
+
+
+ // Test single update, setCurrentMainField1, and transitionToNextState
+ softButtonManager.setCurrentMainField1("It is Wednesday my dudes!");
+ softButtonObject1.transitionToNextState();
+
+
+ // Check that everything got called as expected
+ assertTrue("FileManager.uploadArtworks() did not get called", fileManagerUploadArtworksGotCalled);
+ assertTrue("InternalInterface.sendRPCRequest() did not get called", internalInterfaceSendRPCRequestGotCalled);
+ assertTrue("SoftButtonManger update onComplete() did not get called", softButtonMangerUpdateCompleted);
+
+
+ // Test getSoftButtonObjects
+ assertEquals("Returned softButtonObjects value doesn't match the expected value", softButtonObjects, softButtonManager.getSoftButtonObjects());
+ }
+
+ public void testSoftButtonManagerGetSoftButtonObject() {
+ softButtonManager.setSoftButtonObjects(Arrays.asList(softButtonObject1, softButtonObject2));
+
+
+ // Test get by valid name
+ assertEquals("Returned SoftButtonObject doesn't match the expected value", softButtonObject2, softButtonManager.getSoftButtonObjectByName("object2"));
+
+
+ // Test get by invalid name
+ assertNull("Returned SoftButtonObject doesn't match the expected value", softButtonManager.getSoftButtonObjectByName("object300"));
+
+
+ // Test get by valid id
+ assertEquals("Returned SoftButtonObject doesn't match the expected value", softButtonObject2, softButtonManager.getSoftButtonObjectById(100));
+
+
+ // Test get by invalid id
+ assertNull("Returned SoftButtonObject doesn't match the expected value", softButtonManager.getSoftButtonObjectById(500));
+ }
+
+ public void testSoftButtonState(){
+ // Test SoftButtonState.getName()
+ String nameExpectedValue = "object1-state1";
+ assertEquals("Returned state name doesn't match the expected value", nameExpectedValue, softButtonState1.getName());
+
+
+ // Test SoftButtonState.getArtwork()
+ SdlArtwork artworkExpectedValue = new SdlArtwork("image1", FileType.GRAPHIC_PNG, 1, true);
+ assertTrue("Returned SdlArtwork doesn't match the expected value", Validator.validateSdlFile(artworkExpectedValue, softButtonState1.getArtwork()));
+ SdlArtwork artworkExpectedValue2 = new SdlArtwork(StaticIconName.ALBUM);
+ assertTrue("Returned SdlArtwork doesn't match the expected value", Validator.validateSdlFile(artworkExpectedValue2, softButtonState2.getArtwork()));
+
+
+ // Test SoftButtonState.getSoftButton()
+ SoftButton softButtonExpectedValue = new SoftButton(SoftButtonType.SBT_BOTH, 0);
+ softButtonExpectedValue.setText("o1s1");
+ softButtonExpectedValue.setImage(new Image(artworkExpectedValue.getName(), ImageType.DYNAMIC));
+ assertTrue("Returned SoftButton doesn't match the expected value", Validator.validateSoftButton(softButtonExpectedValue, softButtonState1.getSoftButton()));
+ }
+
+ public void testSoftButtonObject(){
+ // Test SoftButtonObject.getName()
+ assertEquals("Returned object name doesn't match the expected value", "object1", softButtonObject1.getName());
+
+
+ // Test SoftButtonObject.getCurrentState()
+ assertEquals("Returned current state doesn't match the expected value", softButtonState1, softButtonObject1.getCurrentState());
+
+
+ // Test SoftButtonObject.getCurrentStateName()
+ assertEquals("Returned current state name doesn't match the expected value", softButtonState1.getName(), softButtonObject1.getCurrentStateName());
+
+
+ // Test SoftButtonObject.getButtonId()
+ assertEquals("Returned button Id doesn't match the expected value", 0, softButtonObject1.getButtonId());
+
+
+ // Test SoftButtonObject.getCurrentStateSoftButton()
+ SoftButton softButtonExpectedValue = new SoftButton(SoftButtonType.SBT_TEXT, 0);
+ softButtonExpectedValue.setText("o2s1");
+ assertTrue("Returned current state SoftButton doesn't match the expected value", Validator.validateSoftButton(softButtonExpectedValue, softButtonObject2.getCurrentStateSoftButton()));
+
+
+ // Test SoftButtonObject.getStates()
+ assertEquals("Returned object states doesn't match the expected value", Arrays.asList(softButtonState1, softButtonState2), softButtonObject1.getStates());
+
+
+ // Test SoftButtonObject.transitionToNextState()
+ assertEquals(softButtonState1, softButtonObject1.getCurrentState());
+ softButtonObject1.transitionToNextState();
+ assertEquals(softButtonState2, softButtonObject1.getCurrentState());
+
+
+ // Test SoftButtonObject.transitionToStateByName() - transitioning to a none existing state
+ boolean success = softButtonObject1.transitionToStateByName("none existing name");
+ assertFalse(success);
+
+
+ // Test SoftButtonObject.transitionToStateByName() - transitioning to an existing state
+ success = softButtonObject1.transitionToStateByName("object1-state1");
+ assertTrue(success);
+ assertEquals(softButtonState1, softButtonObject1.getCurrentState());
+ }
+}
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
new file mode 100644
index 000000000..d063f52e3
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java
@@ -0,0 +1,546 @@
+package com.smartdevicelink.managers.screen;
+
+import android.content.Context;
+import android.net.Uri;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.managers.BaseSubManager;
+import com.smartdevicelink.managers.file.FileManager;
+import com.smartdevicelink.managers.file.filetypes.SdlArtwork;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.rpc.DisplayCapabilities;
+import com.smartdevicelink.proxy.rpc.MetadataTags;
+import com.smartdevicelink.proxy.rpc.Show;
+import com.smartdevicelink.proxy.rpc.TextField;
+import com.smartdevicelink.proxy.rpc.enums.FileType;
+import com.smartdevicelink.proxy.rpc.enums.HMILevel;
+import com.smartdevicelink.proxy.rpc.enums.MetadataType;
+import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
+import com.smartdevicelink.proxy.rpc.enums.TextFieldName;
+
+import org.json.JSONException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library manager class :
+ * {@link com.smartdevicelink.managers.screen.TextAndGraphicManager}
+ */
+public class TextAndGraphicManagerTests extends AndroidTestCase2 {
+
+ // SETUP / HELPERS
+ private TextAndGraphicManager textAndGraphicManager;
+ private SdlArtwork testArtwork;
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+ Context mTestContext = this.getContext();
+ // mock things
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
+ SoftButtonManager softButtonManager = mock(SoftButtonManager.class);
+
+ testArtwork = new SdlArtwork();
+ testArtwork.setName("testFile");
+ Uri uri = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl");
+ testArtwork.setUri(uri);
+ testArtwork.setType(FileType.GRAPHIC_PNG);
+
+ textAndGraphicManager = new TextAndGraphicManager(internalInterface, fileManager, softButtonManager);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private DisplayCapabilities getDisplayCapability(int numberOfMainFields){
+
+ TextField mainField1 = new TextField();
+ mainField1.setName(TextFieldName.mainField1);
+ TextField mainField2 = new TextField();
+ mainField2.setName(TextFieldName.mainField2);
+ TextField mainField3 = new TextField();
+ mainField3.setName(TextFieldName.mainField3);
+ TextField mainField4 = new TextField();
+ mainField4.setName(TextFieldName.mainField4);
+
+ List<TextField> textFieldList = new ArrayList<>();
+
+ textFieldList.add(mainField1);
+ textFieldList.add(mainField2);
+ textFieldList.add(mainField3);
+ textFieldList.add(mainField4);
+
+ List<TextField> returnList = new ArrayList<>();
+
+ if (numberOfMainFields > 0){
+ for (int i = 0; i < numberOfMainFields; i++) {
+ returnList.add(textFieldList.get(i));
+ }
+ }
+
+ DisplayCapabilities displayCapabilities = new DisplayCapabilities();
+ displayCapabilities.setTextFields(returnList);
+
+ return displayCapabilities;
+ }
+
+ public void testInstantiation(){
+
+ assertNull(textAndGraphicManager.getTextField1());
+ assertNull(textAndGraphicManager.getTextField2());
+ assertNull(textAndGraphicManager.getTextField3());
+ assertNull(textAndGraphicManager.getTextField4());
+ assertNull(textAndGraphicManager.getMediaTrackTextField());
+ assertNull(textAndGraphicManager.getPrimaryGraphic());
+ assertNull(textAndGraphicManager.getSecondaryGraphic());
+ assertEquals(textAndGraphicManager.getTextAlignment(), TextAlignment.CENTERED);
+ assertNull(textAndGraphicManager.getTextField1Type());
+ assertNull(textAndGraphicManager.getTextField2Type());
+ assertNull(textAndGraphicManager.getTextField3Type());
+ assertNull(textAndGraphicManager.getTextField4Type());
+
+ assertNotNull(textAndGraphicManager.currentScreenData);
+ assertNull(textAndGraphicManager.inProgressUpdate);
+ assertNull(textAndGraphicManager.queuedImageUpdate);
+ assertFalse(textAndGraphicManager.hasQueuedUpdate);
+ assertNull(textAndGraphicManager.displayCapabilities);
+ assertEquals(textAndGraphicManager.currentHMILevel, HMILevel.HMI_NONE);
+ assertFalse(textAndGraphicManager.isDirty);
+ assertEquals(textAndGraphicManager.getState(), BaseSubManager.SETTING_UP);
+ assertNotNull(textAndGraphicManager.getBlankArtwork());
+ }
+
+ public void testGetMainLines(){
+
+ // We want to test that the looping works. By default, it will return 4 if display cap is null
+
+ // Null test
+ assertEquals(textAndGraphicManager.getNumberOfLines(), 4);
+
+ // 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.displayCapabilities = getDisplayCapability(3);
+ assertEquals(textAndGraphicManager.getNumberOfLines(), 3);
+ }
+
+ public void testAssemble1Line(){
+
+ Show inputShow = new Show();
+
+ // Force it to return display with support for only 1 line of text
+ textAndGraphicManager.displayCapabilities = getDisplayCapability(1);
+
+ textAndGraphicManager.setTextField1("It is");
+ textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY);
+
+ Show assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+
+ // test tags (just 1)
+ MetadataTags tags = assembledShow.getMetadataTags();
+ List<MetadataType> tagsList = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ assertEquals(tags.getMainField1(), tagsList);
+
+ textAndGraphicManager.setTextField2("Wednesday");
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is - Wednesday");
+
+ textAndGraphicManager.setTextField3("My");
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My");
+
+ textAndGraphicManager.setTextField4("Dudes");
+ textAndGraphicManager.setTextField4Type(MetadataType.CURRENT_TEMPERATURE);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My - Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList.add(MetadataType.CURRENT_TEMPERATURE);
+ assertEquals(tags.getMainField1(), tagsList);
+
+ // For some obscurity, lets try setting just fields 2 and 4 for a 1 line display
+ textAndGraphicManager.setTextField1(null);
+ textAndGraphicManager.setTextField3(null);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "Wednesday - Dudes");
+ }
+
+ public void testAssemble2Lines() {
+
+ Show inputShow = new Show();
+
+ // Force it to return display with support for only 2 lines of text
+ textAndGraphicManager.displayCapabilities = getDisplayCapability(2);
+
+ textAndGraphicManager.setTextField1("It is");
+ textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY);
+
+ Show assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+
+ // 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");
+
+ // 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 - Wednesday");
+ assertEquals(assembledShow.getMainField2(), "My");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ tagsList.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.MEDIA_ALBUM);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+
+ textAndGraphicManager.setTextField4("Dudes");
+ textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is - Wednesday");
+ assertEquals(assembledShow.getMainField2(), "My - Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ tagsList.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.MEDIA_STATION);
+ tagsList2.add(MetadataType.MEDIA_ALBUM);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+
+ // For some obscurity, lets try setting just fields 2 and 4 for a 2 line display
+ textAndGraphicManager.setTextField1(null);
+ textAndGraphicManager.setTextField3(null);
+ textAndGraphicManager.setTextField1Type(null);
+ textAndGraphicManager.setTextField3Type(null);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "Wednesday");
+ assertEquals(assembledShow.getMainField2(), "Dudes");
+
+ // And 3 fields without setting 1
+ textAndGraphicManager.setTextField3("My");
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "Wednesday");
+ assertEquals(assembledShow.getMainField2(), "My - Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ tagsList.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList2.add(MetadataType.MEDIA_STATION);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+ }
+
+ public void testAssemble3Lines() {
+
+ Show inputShow = new Show();
+
+ // Force it to return display with support for only 3 lines of text
+ textAndGraphicManager.displayCapabilities = getDisplayCapability(3);
+
+ textAndGraphicManager.setTextField1("It is");
+ textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY);
+
+ Show assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ assertEquals(assembledShow.getMainField1(), "It is");
+ assertEquals(assembledShow.getMainField2(), "");
+ assertEquals(assembledShow.getMainField3(), "");
+
+ // 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(), "");
+
+ // 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");
+
+ // 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 - Dudes");
+
+ // test tags
+ tags = assembledShow.getMetadataTags();
+ tagsList = new ArrayList<>();
+ tagsList2 = new ArrayList<>();
+ tagsList3 = new ArrayList<>();
+ tagsList.add(MetadataType.HUMIDITY);
+ tagsList2.add(MetadataType.CURRENT_TEMPERATURE);
+ tagsList3.add(MetadataType.MEDIA_ALBUM);
+ tagsList3.add(MetadataType.MEDIA_STATION);
+ assertEquals(tags.getMainField1(), tagsList);
+ assertEquals(tags.getMainField2(), tagsList2);
+ assertEquals(tags.getMainField3(), tagsList3);
+
+ // Someone might not want to set the fields in order? We should handle that
+ textAndGraphicManager.setTextField1(null);
+
+ assembledShow = textAndGraphicManager.assembleShowText(inputShow);
+ try {
+ System.out.println(assembledShow.serializeJSON().toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ assertEquals(assembledShow.getMainField2(), "Wednesday");
+ assertEquals(assembledShow.getMainField3(), "My - Dudes");
+ }
+
+ public void testAssemble4Lines() {
+
+ Show inputShow = new Show();
+
+ // Force it to return display with support for only 4 lines of text
+ textAndGraphicManager.displayCapabilities = getDisplayCapability(4);
+
+ 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(), "");
+
+ // 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);
+ }
+
+ public void testMediaTrackTextField() {
+
+ String songTitle = "Wild For The Night";
+ textAndGraphicManager.setMediaTrackTextField(songTitle);
+ assertEquals(textAndGraphicManager.getMediaTrackTextField(), songTitle);
+ }
+
+ public void testAlignment() {
+
+ textAndGraphicManager.setTextAlignment(TextAlignment.LEFT_ALIGNED);
+ assertEquals(textAndGraphicManager.getTextAlignment(), TextAlignment.LEFT_ALIGNED);
+ }
+
+ public void testExtractTextFromShow(){
+
+ Show mainShow = new Show();
+ mainShow.setMainField1("test");
+ mainShow.setMainField3("Sauce");
+ mainShow.setMainField4("");
+
+ Show newShow = textAndGraphicManager.extractTextFromShow(mainShow);
+
+ assertEquals(newShow.getMainField1(), "test");
+ assertEquals(newShow.getMainField3(), "Sauce");
+ assertEquals(newShow.getMainField4(), "");
+ assertNull(newShow.getMainField2());
+ }
+
+ // TEST IMAGES
+
+ public void testSetPrimaryGraphic() {
+ textAndGraphicManager.setPrimaryGraphic(testArtwork);
+ assertEquals(textAndGraphicManager.getPrimaryGraphic(), testArtwork);
+ }
+
+ public void testSetSecondaryGraphic() {
+ textAndGraphicManager.setSecondaryGraphic(testArtwork);
+ assertEquals(textAndGraphicManager.getSecondaryGraphic(), testArtwork);
+ }
+
+ // TEST DISPOSE
+
+ public void testDispose() {
+ textAndGraphicManager.dispose();
+
+ assertNull(textAndGraphicManager.getTextField1());
+ assertNull(textAndGraphicManager.getTextField2());
+ assertNull(textAndGraphicManager.getTextField3());
+ assertNull(textAndGraphicManager.getTextField4());
+ assertNull(textAndGraphicManager.getMediaTrackTextField());
+ assertNull(textAndGraphicManager.getPrimaryGraphic());
+ assertNull(textAndGraphicManager.getSecondaryGraphic());
+ assertNull(textAndGraphicManager.getTextAlignment());
+ assertNull(textAndGraphicManager.getTextField1Type());
+ assertNull(textAndGraphicManager.getTextField2Type());
+ assertNull(textAndGraphicManager.getTextField3Type());
+ assertNull(textAndGraphicManager.getTextField4Type());
+ assertNotNull(textAndGraphicManager.getBlankArtwork());
+ assertNull(textAndGraphicManager.currentScreenData);
+ assertNull(textAndGraphicManager.inProgressUpdate);
+ assertNull(textAndGraphicManager.queuedImageUpdate);
+ assertFalse(textAndGraphicManager.hasQueuedUpdate);
+ assertNull(textAndGraphicManager.displayCapabilities);
+ assertFalse(textAndGraphicManager.isDirty);
+ assertEquals(textAndGraphicManager.getState(), BaseSubManager.SHUTDOWN);
+ }
+}
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
new file mode 100644
index 000000000..e0febdb51
--- /dev/null
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/video/VideoStreamManagerTests.java
@@ -0,0 +1,282 @@
+package com.smartdevicelink.managers.video;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.smartdevicelink.AndroidTestCase2;
+import com.smartdevicelink.managers.CompletionListener;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
+import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
+import com.smartdevicelink.proxy.rpc.OnHMIStatus;
+import com.smartdevicelink.proxy.rpc.OnTouchEvent;
+import com.smartdevicelink.proxy.rpc.TouchEvent;
+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.listeners.OnRPCNotificationListener;
+import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
+import com.smartdevicelink.streaming.video.VideoStreamingParameters;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.util.Version;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * This is a unit test class for the SmartDeviceLink video streaming manager class :
+ * {@link VideoStreamManager}
+ */
+public class VideoStreamManagerTests extends AndroidTestCase2 {
+ public static final String TAG = "VideoStreamManagerTests";
+ private Context mTestContext;
+ private static boolean touchEventOccured = false;
+
+ // SETUP / HELPERS
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+ mTestContext = this.getContext();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // TEST CLASSES
+
+ public static class TestPresentation extends SdlRemoteDisplay {
+ View simulatedView = new View(this.getContext());
+
+ public TestPresentation(Context context, Display display) {
+ super(context, display);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(simulatedView);
+ }
+
+ @Override
+ public boolean onTouchEvent(@NonNull MotionEvent event) {
+ touchEventOccured = true;
+ return super.onTouchEvent(event);
+ }
+ }
+
+ // TESTS
+
+ public void testInitialization(){
+ ISdl internalInterface = mock(ISdl.class);
+ when(internalInterface.getProtocolVersion()).thenReturn(new Version(5,1,0));
+
+ Answer<Void> onAddServiceListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ SessionType sessionType = (SessionType) args[0];
+ ISdlServiceListener sdlServiceListener = (ISdlServiceListener) args[1];
+ assertEquals(sessionType, SessionType.NAV);
+ assertNotNull(sdlServiceListener);
+ return null;
+ }
+ };
+
+ doAnswer(onAddServiceListener).when(internalInterface).addServiceListener(any(SessionType.class), any(ISdlServiceListener.class));
+
+ VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
+ videoStreamManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ }
+ });
+ }
+
+ public void testHMILevelNotFull(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ when(internalInterface.getProtocolVersion()).thenReturn((new Version(5,0,0)));
+ when(internalInterface.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)).thenReturn(true);
+
+ final VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
+ videoStreamManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertNull(videoStreamManager.startVideoService(
+ new VideoStreamingParameters(), false));
+ }
+ });
+ }
+
+ public void testRemoteDisplayStream(){
+ ISdl internalInterface = mock(ISdl.class);
+
+ final Set<Object> listenerSet = new HashSet<>();
+
+ when(internalInterface.getProtocolVersion()).thenReturn(new Version(5,0,0));
+ when(internalInterface.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)).thenReturn(true);
+
+ Answer<Void> onGetCapability = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ OnSystemCapabilityListener systemCapabilityListener = (OnSystemCapabilityListener) args[1];
+ systemCapabilityListener.onCapabilityRetrieved(Test.GENERAL_VIDEOSTREAMINGCAPABILITY);
+ return null;
+ }
+ };
+
+ doAnswer(onGetCapability).when(internalInterface).getCapability(eq(SystemCapabilityType.VIDEO_STREAMING), any(OnSystemCapabilityListener.class));
+
+ Answer<Void> onAddServiceListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ listenerSet.add(args[1]);
+ return null;
+ }
+ };
+
+ doAnswer(onAddServiceListener).when(internalInterface).addServiceListener(eq(SessionType.NAV), any(ISdlServiceListener.class));
+
+ final OnRPCNotificationListener[] hmiListener = {null};
+
+ Answer<Void> onAddHMIListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ hmiListener[0] = (OnRPCNotificationListener) args[1];
+ listenerSet.add(args[1]);
+ return null;
+ }
+ };
+
+ doAnswer(onAddHMIListener).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCNotificationListener.class));
+
+ Answer<Void> onAddTouchListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ listenerSet.add(args[1]);
+ return null;
+ }
+ };
+
+ doAnswer(onAddTouchListener).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_TOUCH_EVENT), any(OnRPCNotificationListener.class));
+
+ Answer<Void> onRemoveRPCNotificationListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ listenerSet.remove(args[1]);
+ return null;
+ }
+ };
+
+ doAnswer(onRemoveRPCNotificationListener).when(internalInterface).removeOnRPCNotificationListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCNotificationListener.class));
+ doAnswer(onRemoveRPCNotificationListener).when(internalInterface).removeOnRPCNotificationListener(eq(FunctionID.ON_TOUCH_EVENT), any(OnRPCNotificationListener.class));
+
+ Answer<Void> onRemoveServiceListener = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ listenerSet.remove(args[1]);
+ return null;
+ }
+ };
+
+ doAnswer(onRemoveServiceListener).when(internalInterface).removeServiceListener(eq(SessionType.NAV), any(ISdlServiceListener.class));
+
+ when(internalInterface.startVideoStream(anyBoolean(), any(VideoStreamingParameters.class))).thenReturn(new IVideoStreamListener() {
+ @Override
+ public void sendFrame(byte[] data, int offset, int length, long presentationTimeUs) throws ArrayIndexOutOfBoundsException {}
+ @Override
+ public void sendFrame(ByteBuffer data, long presentationTimeUs) {}
+ });
+
+ when(internalInterface.getCapability(SystemCapabilityType.VIDEO_STREAMING)).thenReturn(Test.GENERAL_VIDEOSTREAMINGCAPABILITY);
+
+ final VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
+ videoStreamManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ assertTrue(listenerSet.size() == 3);
+
+ OnHMIStatus fullNotification = new OnHMIStatus();
+ fullNotification.setHmiLevel(HMILevel.HMI_FULL);
+ hmiListener[0].onNotified(fullNotification);
+
+ videoStreamManager.startRemoteDisplayStream(mTestContext, TestPresentation.class, null, false);
+
+ //assertTrue(touchEventOccured);
+
+ videoStreamManager.dispose();
+ assertTrue(listenerSet.isEmpty());
+ }
+ });
+
+ }
+
+ public void testConvertTouchEvent(){
+ ISdl internalInterface = mock(ISdl.class);
+ when(internalInterface.getProtocolVersion()).thenReturn(new Version(5,1,0));
+
+ final VideoStreamManager videoStreamManager = new VideoStreamManager(internalInterface);
+ videoStreamManager.start(new CompletionListener() {
+ @Override
+ public void onComplete(boolean success) {
+ assertTrue(success);
+ OnTouchEvent testOnTouchEvent = new OnTouchEvent();
+ TouchEvent touchEvent = Test.GENERAL_TOUCHEVENT;
+ testOnTouchEvent.setEvent(Collections.singletonList(touchEvent));
+ testOnTouchEvent.setType(Test.GENERAL_TOUCHTYPE);
+ MotionEvent motionEvent;
+
+ // Touch one pointer (100)
+ motionEvent = videoStreamManager.convertTouchEvent(testOnTouchEvent);
+ assertEquals(motionEvent.getAction(), MotionEvent.ACTION_DOWN);
+
+ // Touch another pointer (101) without release
+ touchEvent.setId(Test.GENERAL_INT + 1);
+ testOnTouchEvent.setEvent(Collections.singletonList(touchEvent));
+ motionEvent = videoStreamManager.convertTouchEvent(testOnTouchEvent);
+ assertEquals(motionEvent.getAction(), MotionEvent.ACTION_POINTER_DOWN);
+
+ // Release one of the pointers (101)
+ testOnTouchEvent.setType(TouchType.END);
+ motionEvent = videoStreamManager.convertTouchEvent(testOnTouchEvent);
+ assertEquals(motionEvent.getAction(), MotionEvent.ACTION_POINTER_UP);
+
+ // Release the other pointer (100)
+ touchEvent.setId(Test.GENERAL_INT);
+ testOnTouchEvent.setEvent(Collections.singletonList(touchEvent));
+ motionEvent = videoStreamManager.convertTouchEvent(testOnTouchEvent);
+ assertEquals(motionEvent.getAction(), MotionEvent.ACTION_UP);
+ }
+ });
+ }
+}