summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicoleYarroch <nicole@livio.io>2019-08-14 11:56:46 -0400
committerNicoleYarroch <nicole@livio.io>2019-08-14 11:56:46 -0400
commit9f1da1b695644b4f13c82d9b3c1be58ecaed0848 (patch)
treec80f88b2d5c07148672d250a30d2004acfb38d54
parent30514fbc3b0671c84387a815907f1159a7529f47 (diff)
downloadsdl_android-9f1da1b695644b4f13c82d9b3c1be58ecaed0848.tar.gz
Added check for canceled threads.
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java47
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java4
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java35
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java45
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java3
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java9
6 files changed, 109 insertions, 34 deletions
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java
index 4d47ba89c..ef106e400 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java
@@ -40,7 +40,6 @@ import com.smartdevicelink.managers.BaseSubManager;
import com.smartdevicelink.managers.file.FileManager;
import com.smartdevicelink.proxy.interfaces.ISdl;
import com.smartdevicelink.proxy.rpc.KeyboardProperties;
-import com.smartdevicelink.proxy.rpc.SdlMsgVersion;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.KeyboardLayout;
import com.smartdevicelink.proxy.rpc.enums.KeypressMode;
@@ -48,7 +47,7 @@ import com.smartdevicelink.proxy.rpc.enums.Language;
import com.smartdevicelink.proxy.rpc.enums.SystemContext;
import com.smartdevicelink.proxy.rpc.enums.TriggerSource;
-import org.junit.Test;
+import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
@@ -57,15 +56,16 @@ import java.util.HashSet;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
+import static com.smartdevicelink.managers.BaseSubManager.READY;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ChoiceSetManagerTests extends AndroidTestCase2 {
-
private ChoiceSetManager csm;
@Override
@@ -243,39 +243,49 @@ public class ChoiceSetManagerTests extends AndroidTestCase2 {
}
}
- public void testPresentingKeyboard() {}
+ public void testPresentingKeyboardShouldReturnCancelIDIfKeyboardCanBeSent() {
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
- public void testPresentingKeyboardWithDeprecatedMethod() {}
+ ChoiceSetManager newCSM = new ChoiceSetManager(internalInterface, fileManager);
+ ChoiceSetManager partialMockCSM = spy(newCSM);
+ when(partialMockCSM.isReady()).thenReturn(true);
- public void testPresentingKeyboardWhenKeyboardCannotBeSentToCore() {}
+ Integer cancelId = partialMockCSM.presentKeyboard("initial text", mock(KeyboardListener.class), mock(KeyboardProperties.class));
+ assertNotNull(cancelId);
+ }
- public void testDismissKeyboardThatIsExecuting(){
- Integer testCancelID = 42;
- PresentKeyboardOperation testKeyboardOp = mock(PresentKeyboardOperation.class);
- doReturn(testCancelID).when(testKeyboardOp).getCancelID();
- doReturn(true).when(testKeyboardOp).isExecuting();
- csm.currentlyPresentedKeyboardOperation = testKeyboardOp;
- csm.dismissKeyboard(testCancelID);
- verify(testKeyboardOp, times(1)).dismissKeyboard();
+ public void testPresentingKeyboardShouldNotReturnCancelIDIfKeyboardCannotBeSent() {
+ ISdl internalInterface = mock(ISdl.class);
+ FileManager fileManager = mock(FileManager.class);
+
+ ChoiceSetManager newCSM = new ChoiceSetManager(internalInterface, fileManager);
+ ChoiceSetManager partialMockCSM = spy(newCSM);
+ when(partialMockCSM.isReady()).thenReturn(false);
+
+ Integer cancelId = partialMockCSM.presentKeyboard("initial text", mock(KeyboardListener.class), mock(KeyboardProperties.class));
+ assertNull(cancelId);
}
- public void testDismissKeyboardThatIsNotExecuting(){
+ public void testDismissingExecutingKeyboard(){
Integer testCancelID = 42;
PresentKeyboardOperation testKeyboardOp = mock(PresentKeyboardOperation.class);
- doReturn(false).when(testKeyboardOp).isExecuting();
doReturn(testCancelID).when(testKeyboardOp).getCancelID();
csm.currentlyPresentedKeyboardOperation = testKeyboardOp;
csm.dismissKeyboard(testCancelID);
verify(testKeyboardOp, times(1)).dismissKeyboard();
}
- public void testDismissingMultipleKeyboards(){
+ public void testDismissingQueuedKeyboard(){
Integer testCancelID = 42;
+
+ // Currently executing operation
PresentKeyboardOperation testKeyboardOp = mock(PresentKeyboardOperation.class);
doReturn(true).when(testKeyboardOp).isExecuting();
doReturn(96).when(testKeyboardOp).getCancelID();
csm.currentlyPresentedKeyboardOperation = testKeyboardOp;
+ // Queued operations
PresentKeyboardOperation testKeyboardOp2 = mock(PresentKeyboardOperation.class);
doReturn(true).when(testKeyboardOp2).isExecuting();
doReturn(testCancelID).when(testKeyboardOp2).getCancelID();
@@ -283,6 +293,7 @@ public class ChoiceSetManagerTests extends AndroidTestCase2 {
testOperationQueue.add(testKeyboardOp2);
csm.operationQueue = testOperationQueue;
+ // Queued operation should be canceled
csm.dismissKeyboard(testCancelID);
verify(testKeyboardOp, times(0)).dismissKeyboard();
verify(testKeyboardOp2, times(1)).dismissKeyboard();
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java
index 1eb74c06d..740644135 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java
@@ -46,7 +46,6 @@ public class ChoiceSetTests extends AndroidTestCase2 {
private ChoiceSetLayout layout;
private List<ChoiceCell> choices;
private Integer defaultTimeout;
- private Integer testCancelID;
private Boolean canceledHandlerCalled;
@Override
@@ -57,7 +56,6 @@ public class ChoiceSetTests extends AndroidTestCase2 {
layout = ChoiceSetLayout.CHOICE_SET_LAYOUT_LIST;
defaultTimeout = 10;
choices = Arrays.asList(new ChoiceCell(Test.GENERAL_STRING), new ChoiceCell(Test.GENERAL_STRING));
- testCancelID = Test.GENERAL_INTEGER;
canceledHandlerCalled = false;
}
@@ -113,8 +111,6 @@ public class ChoiceSetTests extends AndroidTestCase2 {
}
};
- assertEquals(Test.MATCH, Test.GENERAL_INTEGER, testCancelID);
-
choiceSet.cancel();
assertEquals(Test.MATCH, canceledHandlerCalled.booleanValue(), true);
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java
index 6578741b2..273f7f23c 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java
@@ -119,7 +119,7 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
return properties;
}
- public void testCancelingTheChoiceSetSuccessfullyIfThreadIsRunning(){
+ public void testCancelingChoiceSetSuccessfullyIfThreadIsRunning(){
presentChoiceSetOperation.run();
assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), true);
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
@@ -148,7 +148,7 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
}
- public void testCancelingTheChoiceSetUnsuccessfullyIfThreadIsRunning(){
+ public void testCancelingChoiceSetUnsuccessfullyIfThreadIsRunning(){
presentChoiceSetOperation.run();
assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), true);
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
@@ -177,7 +177,7 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
}
- public void testCancelingTheChoiceSetIfThreadHasFinished(){
+ public void testCancelingChoiceSetIfThreadHasFinished(){
presentChoiceSetOperation.run();
presentChoiceSetOperation.finishOperation();
@@ -192,7 +192,7 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), true);
}
- public void testCancelingTheChoiceSetIfThreadHasNotYetRun(){
+ public void testCancelingChoiceSetIfThreadHasNotYetRun(){
assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), false);
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
@@ -203,14 +203,15 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
// Once the thread has started
presentChoiceSetOperation.run();
- // Make sure it doesn't sent a `CancelInteraction` RPC
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is sent
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), false);
assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), true);
}
- public void testCancelingTheChoiceSetIfHeadUnitDoesNotSupportFeature(){
+ public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeature(){
// Only supported with RPC spec versions 6.0.0+
presentChoiceSetOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
presentChoiceSetOperation.run();
@@ -222,4 +223,26 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
}
+
+ public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeatureButThreadIsNotRunning(){
+ // Only supported with RPC spec versions 6.0.0+
+ presentChoiceSetOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
+
+ assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), false);
+ assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), false);
+
+ choiceSet.cancel();
+
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+
+ // Once the thread has started
+ presentChoiceSetOperation.run();
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
+
+ assertEquals(presentChoiceSetOperation.isExecuting().booleanValue(), false);
+ assertEquals(presentChoiceSetOperation.isFinished().booleanValue(), true);
+ }
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java
index 39cd71b5a..336c6ac9f 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java
@@ -114,7 +114,7 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
return properties;
}
- public void testCancelingTheKeyboardSuccessfullyIfThreadIsRunning(){
+ public void testCancelingKeyboardSuccessfullyIfThreadIsRunning(){
presentKeyboardOperation.run();
assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), true);
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
@@ -143,7 +143,7 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
}
- public void testCancelingTheKeyboardUnsuccessfullyIfThreadIsRunning(){
+ public void testCancelingKeyboardUnsuccessfullyIfThreadIsRunning(){
presentKeyboardOperation.run();
assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), true);
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
@@ -172,7 +172,7 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
}
- public void testCancelingTheKeyboardIfThreadHasFinished(){
+ public void testCancelingKeyboardIfThreadHasFinished(){
presentKeyboardOperation.run();
presentKeyboardOperation.finishOperation();
@@ -187,15 +187,52 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), true);
}
- public void testCancelingTheKeyboardIfThreadHasNotYetRun(){
+ public void testCancelingKeyboardIfThreadHasNotYetRun(){
assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), false);
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
presentKeyboardOperation.dismissKeyboard();
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is sent
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), false);
assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
}
+
+ public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeature(){
+ // Only supported with RPC spec versions 6.0.0+
+ presentKeyboardOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
+ presentKeyboardOperation.run();
+
+ assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), true);
+ assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
+
+ presentKeyboardOperation.dismissKeyboard();
+
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ }
+
+ public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeatureButThreadIsNotRunning(){
+ // Only supported with RPC spec versions 6.0.0+
+ presentKeyboardOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
+
+ assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), false);
+ assertEquals(presentKeyboardOperation.isFinished().booleanValue(), false);
+
+ presentKeyboardOperation.dismissKeyboard();
+
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+
+ // Once the thread has started
+ presentKeyboardOperation.run();
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
+
+ assertEquals(presentKeyboardOperation.isExecuting().booleanValue(), false);
+ assertEquals(presentKeyboardOperation.isFinished().booleanValue(), true);
+ }
}
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java
index a3db8f38a..7fc02f93d 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java
@@ -47,7 +47,6 @@ import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.DisplayCapabilities;
import com.smartdevicelink.proxy.rpc.KeyboardProperties;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
-import com.smartdevicelink.proxy.rpc.SdlMsgVersion;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
import com.smartdevicelink.proxy.rpc.enums.InteractionMode;
import com.smartdevicelink.proxy.rpc.enums.KeyboardLayout;
@@ -638,7 +637,7 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
- private boolean isReady(){
+ boolean isReady(){
if (getState() != READY){
DebugTool.logWarning("Choice Manager In Not-Ready State");
return false;
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java
index d177e4f8b..fb33cb477 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java
@@ -106,6 +106,11 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
}
private void start(){
+ if (Thread.currentThread().isInterrupted()) {
+ finishOperation();
+ return;
+ }
+
// Check if we're using a keyboard (searchable) choice set and setup keyboard properties if we need to
if (keyboardListener != null && choiceSet.getCustomKeyboardConfiguration() != null){
keyboardProperties = choiceSet.getCustomKeyboardConfiguration();
@@ -322,6 +327,10 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
keyboardRPCListener = new OnRPCNotificationListener() {
@Override
public void onNotified(RPCNotification notification) {
+ if (Thread.currentThread().isInterrupted()) {
+ finishOperation();
+ return;
+ }
if (keyboardListener == null){
DebugTool.logError("Received Keyboard Input But Listener is null");