diff options
author | NicoleYarroch <nicole@livio.io> | 2019-08-14 11:56:46 -0400 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2019-08-14 11:56:46 -0400 |
commit | 9f1da1b695644b4f13c82d9b3c1be58ecaed0848 (patch) | |
tree | c80f88b2d5c07148672d250a30d2004acfb38d54 | |
parent | 30514fbc3b0671c84387a815907f1159a7529f47 (diff) | |
download | sdl_android-9f1da1b695644b4f13c82d9b3c1be58ecaed0848.tar.gz |
Added check for canceled threads.
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"); |