summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilal Alsharifi <599206+bilal-alsharifi@users.noreply.github.com>2019-09-12 08:27:08 -0400
committerNicoleYarroch <nicole@livio.io>2019-09-12 08:27:08 -0400
commit70f343d0f237b2e4bb2164d1bc9d2171b2e45790 (patch)
tree0ed9cbf5e32bc8df02598041fedbb02b1af30d29
parentb7039e3c32488c67ad46e13bbf48137357f3e125 (diff)
downloadsdl_android-70f343d0f237b2e4bb2164d1bc9d2171b2e45790.tar.gz
Make ChoiceSetManager operations blocking (#1155)feature/cancel_interaction_RPC
* Add blocking operations support * Update AsynchronousOperation.ToString() * Handle some missing onError logic in operations * Update cancel() and isCancelled() to use the current thread * Avoid interrupting thread when canceling operations * Clean up BaseChoiceSetManager * fix NPE from pendingSet * fix failing tests in ChoiceSetManagerTests * Comment out cancel interaction tests temporarily * Avoid using thread interruptions in AsynchronousOperation * Update AsynchronousOperation.toString() * Fixed print statement crashing if no operating thread * Fixed present choice set cancel operation tests * Fixed spacing issues * Added additional assert + fixed doc grammar * Fixed cancel keyboard operation tests * Modified termination duration in test cases
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java6
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperationTests.java151
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java137
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/AsynchronousOperation.java63
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java64
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/CheckChoiceVROptionalOperation.java13
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/DeleteChoicesOperation.java9
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperation.java9
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentChoiceSetOperation.java23
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperation.java13
10 files changed, 348 insertions, 140 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 7c7874c30..b8af1a68c 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
@@ -104,7 +104,7 @@ public class ChoiceSetManagerTests extends AndroidTestCase2 {
assertEquals(csm.nextChoiceId, 1);
assertTrue(csm.executor.isShutdown());
- assertTrue(csm.isVROptional);
+ assertFalse(csm.isVROptional);
assertEquals(csm.getState(), BaseSubManager.SHUTDOWN);
@@ -246,7 +246,7 @@ public class ChoiceSetManagerTests extends AndroidTestCase2 {
ChoiceSetManager newCSM = new ChoiceSetManager(internalInterface, fileManager);
ChoiceSetManager partialMockCSM = spy(newCSM);
- when(partialMockCSM.isReady()).thenReturn(true);
+ when(partialMockCSM.getState()).thenReturn(BaseSubManager.READY);
Integer cancelId = partialMockCSM.presentKeyboard("initial text", mock(KeyboardProperties.class), mock(KeyboardListener.class));
assertNotNull(cancelId);
@@ -258,7 +258,7 @@ public class ChoiceSetManagerTests extends AndroidTestCase2 {
ChoiceSetManager newCSM = new ChoiceSetManager(internalInterface, fileManager);
ChoiceSetManager partialMockCSM = spy(newCSM);
- when(partialMockCSM.isReady()).thenReturn(false);
+ when(partialMockCSM.getState()).thenReturn(BaseSubManager.ERROR);
Integer cancelId = partialMockCSM.presentKeyboard("initial text", mock(KeyboardProperties.class), mock(KeyboardListener.class));
assertNull(cancelId);
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 7bc2816e3..d8cf5be9d 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
@@ -54,32 +54,42 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.Collections;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
private PresentChoiceSetOperation presentChoiceSetOperation;
private ChoiceSet choiceSet;
private ISdl internalInterface;
+ private KeyboardListener keyboardListener;
+ private ChoiceSetSelectionListener choiceSetSelectionListener;
+
+ private ExecutorService executor;
@Override
public void setUp() throws Exception{
super.setUp();
internalInterface = mock(ISdl.class);
- KeyboardListener keyboardListener = mock(KeyboardListener.class);
- ChoiceSetSelectionListener choiceSetSelectionListener = mock(ChoiceSetSelectionListener.class);
+
+ keyboardListener = mock(KeyboardListener.class);
+ choiceSetSelectionListener = mock(ChoiceSetSelectionListener.class);
ChoiceCell cell1 = new ChoiceCell("Cell1");
cell1.setChoiceId(0);
choiceSet = new ChoiceSet("Test", Collections.singletonList(cell1), choiceSetSelectionListener);
- presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, getKeyBoardProperties(), keyboardListener, choiceSetSelectionListener, Test.GENERAL_INTEGER);
- presentChoiceSetOperation.sdlMsgVersion = new SdlMsgVersion(6, 0);
+
+ executor = Executors.newCachedThreadPool();
}
@Override
@@ -87,14 +97,26 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
super.tearDown();
}
- public void testGetLayoutMode(){
+ private KeyboardProperties getKeyBoardProperties(){
+ KeyboardProperties properties = new KeyboardProperties();
+ properties.setLanguage(Language.EN_US);
+ properties.setKeyboardLayout(KeyboardLayout.QWERTZ);
+ properties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY);
+ return properties;
+ }
+
+ public void testGetLayoutMode(){
// First we will check knowing our keyboard listener is NOT NULL
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, getKeyBoardProperties(), keyboardListener, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+
assertEquals(presentChoiceSetOperation.getLayoutMode(), LayoutMode.LIST_WITH_SEARCH);
presentChoiceSetOperation.keyboardListener = null;
assertEquals(presentChoiceSetOperation.getLayoutMode(), LayoutMode.LIST_ONLY);
}
public void testGetPerformInteraction(){
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, getKeyBoardProperties(), keyboardListener, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+
PerformInteraction pi = presentChoiceSetOperation.getPerformInteraction();
assertEquals(pi.getInitialText(), "Test");
assertNull(pi.getHelpPrompt());
@@ -106,22 +128,27 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
}
public void testSetSelectedCellWithId(){
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, getKeyBoardProperties(), keyboardListener, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+
assertNull(presentChoiceSetOperation.selectedCellRow);
presentChoiceSetOperation.setSelectedCellWithId(0);
assertEquals(presentChoiceSetOperation.selectedCellRow, Integer.valueOf(0));
}
- private KeyboardProperties getKeyBoardProperties(){
- KeyboardProperties properties = new KeyboardProperties();
- properties.setLanguage(Language.EN_US);
- properties.setKeyboardLayout(KeyboardLayout.QWERTZ);
- properties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY);
- return properties;
- }
-
public void testCancelingChoiceSetSuccessfullyIfThreadIsRunning(){
- presentChoiceSetOperation.run();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+ executor.execute(presentChoiceSetOperation);
+
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
+
+ assertTrue(presentChoiceSetOperation.isExecuting());
+ assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
+ choiceSet.cancel();
Answer<Void> cancelInteractionAnswer = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
@@ -140,15 +167,27 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
};
doAnswer(cancelInteractionAnswer).when(internalInterface).sendRPC(any(CancelInteraction.class));
- choiceSet.cancel();
+ verify(internalInterface, times(1)).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
- assertTrue(presentChoiceSetOperation.isExecuting());
+ assertTrue(presentChoiceSetOperation.isExecuting());
assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
}
public void testCancelingChoiceSetUnsuccessfullyIfThreadIsRunning(){
- presentChoiceSetOperation.run();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+ executor.execute(presentChoiceSetOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
+
+ assertTrue(presentChoiceSetOperation.isExecuting());
+ assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
+ choiceSet.cancel();
Answer<Void> cancelInteractionAnswer = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
@@ -167,66 +206,100 @@ public class PresentChoiceSetOperationTests extends AndroidTestCase2 {
};
doAnswer(cancelInteractionAnswer).when(internalInterface).sendRPC(any(CancelInteraction.class));
- choiceSet.cancel();
+ verify(internalInterface, times(1)).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
assertTrue(presentChoiceSetOperation.isExecuting());
assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
}
public void testCancelingChoiceSetIfThreadHasFinished(){
- presentChoiceSetOperation.run();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
presentChoiceSetOperation.finishOperation();
- choiceSet.cancel();
+ assertFalse(presentChoiceSetOperation.isExecuting());
+ assertTrue(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
+ choiceSet.cancel();
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
assertFalse(presentChoiceSetOperation.isExecuting());
assertTrue(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
}
public void testCancelingChoiceSetIfThreadHasNotYetRun(){
- choiceSet.cancel();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
- verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ assertFalse(presentChoiceSetOperation.isExecuting());
+ assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
- // Once the thread has started
- presentChoiceSetOperation.run();
+ choiceSet.cancel();
- // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is sent
- verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
- verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
+ // Once the operation has started
+ executor.execute(presentChoiceSetOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
assertFalse(presentChoiceSetOperation.isExecuting());
assertTrue(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is ever sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
}
public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeature(){
- // Only supported with RPC spec versions 6.0.0+
- presentChoiceSetOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
- presentChoiceSetOperation.run();
+ // Cancel Interaction is only supported on RPC specs v.6.0.0+
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 3));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+ executor.execute(presentChoiceSetOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
+
+ assertTrue(presentChoiceSetOperation.isExecuting());
+ assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
choiceSet.cancel();
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
}
public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeatureButThreadIsNotRunning(){
- // Only supported with RPC spec versions 6.0.0+
- presentChoiceSetOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
+ // Cancel Interaction is only supported on RPC specs v.6.0.0+
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 3));
+ presentChoiceSetOperation = new PresentChoiceSetOperation(internalInterface, choiceSet, InteractionMode.MANUAL_ONLY, null, null, choiceSetSelectionListener, Test.GENERAL_INTEGER);
+
+ assertFalse(presentChoiceSetOperation.isExecuting());
+ assertFalse(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
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));
+ // Once the operation has started
+ executor.execute(presentChoiceSetOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
assertFalse(presentChoiceSetOperation.isExecuting());
assertTrue(presentChoiceSetOperation.isFinished());
+ assertFalse(presentChoiceSetOperation.isCancelled());
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is ever sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
}
-}
+} \ No newline at end of file
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 072fa3f43..486a1c361 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
@@ -53,25 +53,32 @@ import com.smartdevicelink.test.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class PresentKeyboardOperationTests extends AndroidTestCase2 {
private PresentKeyboardOperation presentKeyboardOperation;
+ private KeyboardListener keyboardListener;
private ISdl internalInterface;
+ private ExecutorService executor;
+
@Override
public void setUp() throws Exception{
super.setUp();
internalInterface = mock(ISdl.class);
- KeyboardListener keyboardListener = mock(KeyboardListener.class);
-
- presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, getKeyBoardProperties(), "Test", null, keyboardListener, Test.GENERAL_INTEGER);
+ keyboardListener = mock(KeyboardListener.class);
Answer<Void> setGlobalPropertiesAnswer = new Answer<Void>() {
@Override
@@ -88,7 +95,7 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
};
doAnswer(setGlobalPropertiesAnswer).when(internalInterface).sendRPC(any(SetGlobalProperties.class));
- presentKeyboardOperation.sdlMsgVersion = new SdlMsgVersion(6,0);
+ executor = Executors.newCachedThreadPool();
}
@Override
@@ -96,7 +103,17 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
super.tearDown();
}
+ private KeyboardProperties getKeyBoardProperties(){
+ KeyboardProperties properties = new KeyboardProperties();
+ properties.setLanguage(Language.EN_US);
+ properties.setKeyboardLayout(KeyboardLayout.QWERTZ);
+ properties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY);
+ return properties;
+ }
+
public void testGetPerformInteraction(){
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, getKeyBoardProperties(), "Test", null, keyboardListener, Test.GENERAL_INTEGER);
+
PerformInteraction pi = presentKeyboardOperation.getPerformInteraction();
assertEquals(pi.getInitialText(), "Test");
assertNull(pi.getHelpPrompt());
@@ -106,17 +123,19 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
assertEquals(pi.getCancelID(), Test.GENERAL_INTEGER);
}
- private KeyboardProperties getKeyBoardProperties(){
- KeyboardProperties properties = new KeyboardProperties();
- properties.setLanguage(Language.EN_US);
- properties.setKeyboardLayout(KeyboardLayout.QWERTZ);
- properties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY);
- return properties;
- }
-
public void testCancelingKeyboardSuccessfullyIfThreadIsRunning(){
- presentKeyboardOperation.run();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
+ executor.execute(presentKeyboardOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
+
+ assertTrue(presentKeyboardOperation.isExecuting());
+ assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
+ presentKeyboardOperation.dismissKeyboard();
Answer<Void> cancelInteractionAnswer = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
@@ -135,16 +154,24 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
};
doAnswer(cancelInteractionAnswer).when(internalInterface).sendRPC(any(CancelInteraction.class));
- presentKeyboardOperation.dismissKeyboard();
+ verify(internalInterface, times(1)).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
assertTrue(presentKeyboardOperation.isExecuting());
assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
}
public void testCancelingKeyboardUnsuccessfullyIfThreadIsRunning(){
- presentKeyboardOperation.run();
-
- Answer<Void> cancelInteractionAnswer = new Answer<Void>() {
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
+ executor.execute(presentKeyboardOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
+
+ presentKeyboardOperation.dismissKeyboard();
+ Answer<Void> cancelInteractionAnswer = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
@@ -162,64 +189,100 @@ public class PresentKeyboardOperationTests extends AndroidTestCase2 {
};
doAnswer(cancelInteractionAnswer).when(internalInterface).sendRPC(any(CancelInteraction.class));
- presentKeyboardOperation.dismissKeyboard();
+ verify(internalInterface, times(1)).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
- assertTrue(presentKeyboardOperation.isExecuting());
- assertFalse(presentKeyboardOperation.isFinished());
+ assertTrue(presentKeyboardOperation.isExecuting());
+ assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
}
public void testCancelingKeyboardIfThreadHasFinished(){
- presentKeyboardOperation.run();
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
presentKeyboardOperation.finishOperation();
- presentKeyboardOperation.dismissKeyboard();
+ assertFalse(presentKeyboardOperation.isExecuting());
+ assertTrue(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
+ presentKeyboardOperation.dismissKeyboard();
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
assertFalse(presentKeyboardOperation.isExecuting());
assertTrue(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
}
public void testCancelingKeyboardIfThreadHasNotYetRun(){
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
+
+ assertFalse(presentKeyboardOperation.isExecuting());
+ assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
+
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));
+ // Once the operation has started
+ executor.execute(presentKeyboardOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
assertFalse(presentKeyboardOperation.isExecuting());
- assertFalse(presentKeyboardOperation.isFinished());
+ assertTrue(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is ever sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
}
public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeature(){
- // Only supported with RPC spec versions 6.0.0+
- presentKeyboardOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
- presentKeyboardOperation.run();
+ // Cancel Interaction is only supported on RPC specs v.6.0.0+
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 3));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
+ executor.execute(presentKeyboardOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
assertTrue(presentKeyboardOperation.isExecuting());
assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
presentKeyboardOperation.dismissKeyboard();
verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, times(1)).sendRPC(any(PerformInteraction.class));
}
public void testCancelingChoiceSetIfHeadUnitDoesNotSupportFeatureButThreadIsNotRunning(){
- // Only supported with RPC spec versions 6.0.0+
- presentKeyboardOperation.sdlMsgVersion = new SdlMsgVersion(5, 3);
+ // Cancel Interaction is only supported on RPC specs v.6.0.0+
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 3));
+ presentKeyboardOperation = new PresentKeyboardOperation(internalInterface, null, "Test", null, null, Test.GENERAL_INTEGER);
+
+ assertFalse(presentKeyboardOperation.isExecuting());
+ assertFalse(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
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));
+ // Once the operation has started
+ executor.execute(presentKeyboardOperation);
+ try {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {}
assertFalse(presentKeyboardOperation.isExecuting());
assertTrue(presentKeyboardOperation.isFinished());
+ assertFalse(presentKeyboardOperation.isCancelled());
+
+ // Make sure neither a `CancelInteraction` or `PerformInteraction` RPC is ever sent
+ verify(internalInterface, never()).sendRPC(any(CancelInteraction.class));
+ verify(internalInterface, never()).sendRPC(any(PerformInteraction.class));
}
}
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/AsynchronousOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/AsynchronousOperation.java
index 4ba98b384..c0a1dbb25 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/AsynchronousOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/AsynchronousOperation.java
@@ -37,20 +37,29 @@ package com.smartdevicelink.managers.screen.choiceset;
import com.smartdevicelink.util.DebugTool;
class AsynchronousOperation implements Runnable {
- private Boolean executing;
- private Boolean finished;
+ private static final String TAG = "AsynchronousOperation - ";
+ private Thread thread;
+ private final Object lock;
+ private boolean blocked;
+ private boolean executing;
+ private boolean finished;
+ private boolean cancelled;
AsynchronousOperation() {
+ lock = new Object();
+ blocked = false;
executing = false;
finished = false;
+ cancelled = false;
}
@Override
public void run() {
- DebugTool.logInfo("Starting operation: " + toString());
+ thread = Thread.currentThread();
+ DebugTool.logInfo(TAG + "Starting: " + toString());
if (isCancelled()) {
finished = true;
- DebugTool.logInfo("Operation was cancelled: " + toString());
+ DebugTool.logInfo(TAG + "Operation was cancelled: " + toString());
return;
}
@@ -58,30 +67,56 @@ class AsynchronousOperation implements Runnable {
}
void finishOperation() {
+ unblock();
executing = false;
finished = true;
- DebugTool.logInfo("Finishing operation: " + toString());
+ cancelled = false;
+ DebugTool.logInfo(TAG + "Finishing: " + toString());
}
- public Boolean isAsynchronous() {
- return true;
- }
-
- public Boolean isExecuting() {
+ boolean isExecuting() {
return executing;
}
- public Boolean isFinished() {
+ boolean isFinished() {
return finished;
}
- public Boolean isCancelled() {
- return Thread.currentThread().isInterrupted();
+ void cancel(){
+ cancelled = true;
}
+ boolean isCancelled() {
+ return cancelled;
+ }
+
+ void block(){
+ if (!blocked && !finished) {
+ blocked = true;
+ DebugTool.logInfo(TAG + "Blocking: " + toString());
+ try {
+ synchronized (lock) {
+ lock.wait();
+ }
+ } catch (InterruptedException e) {
+ DebugTool.logWarning(TAG + "InterruptedException: " + toString());
+ finishOperation();
+ }
+ }
+ }
+
+ void unblock(){
+ if (blocked) {
+ blocked = false;
+ DebugTool.logInfo(TAG + "Unblocking: " + toString());
+ synchronized (lock) {
+ lock.notify();
+ }
+ }
+ }
@Override
public String toString() {
- return "Executing: " + executing + ", finished: " + finished + ".";
+ return this.getClass().getSimpleName() + " (OpId: " + System.identityHashCode(this) + ", OpThread:" + (thread != null ? thread.getName() : "no operating thread") + ", currentThread:" + Thread.currentThread().getName() + ", blocked:" + blocked + ", executing:" + executing + ", finished:" + finished + ", cancelled:" + cancelled + ")";
}
}
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 c936548ba..9dc1ff1d6 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
@@ -85,8 +85,6 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
SystemContext currentSystemContext;
HashSet<ChoiceCell> preloadedChoices, pendingPreloadChoices;
ChoiceSet pendingPresentationSet;
- private List<ChoiceCell> waitingChoices;
- private CompletionListener waitingListener;
// We will pass operations into this to be completed
PausableThreadPoolExecutor executor;
@@ -144,9 +142,7 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
pendingPresentationSet = null;
pendingPresentOperation = null;
- waitingChoices = null;
- waitingListener = null;
- isVROptional = true;
+ isVROptional = false;
nextChoiceId = choiceCellIdMin;
nextCancelId = choiceCellCancelIdMin;
@@ -189,10 +185,7 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
*/
public void preloadChoices(@NonNull List<ChoiceCell> choices, @Nullable final CompletionListener listener){
- if (!isReady()){
- waitingChoices = new ArrayList<>(choices);
- waitingListener = listener;
- DebugTool.logInfo("Preload pending choice set manager being ready");
+ if (getState() == ERROR){
return;
}
@@ -222,15 +215,11 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
if (listener != null){
listener.onComplete(true);
}
- waitingChoices = null;
- waitingListener = null;
}else {
DebugTool.logError("There was an error pre loading choice cells");
- if (listener != null){
+ if (listener != null) {
listener.onComplete(false);
}
- waitingChoices = null;
- waitingListener = null;
}
}
});
@@ -247,7 +236,10 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
*/
public void deleteChoices(@NonNull List<ChoiceCell> choices){
- if (!isReady()){ return; }
+ if (getState() == ERROR) {
+ DebugTool.logWarning("Choice Manager In Error State");
+ return;
+ }
// Find cells to be deleted that are already uploaded or are pending upload
final HashSet<ChoiceCell> cellsToBeDeleted = choicesToBeDeletedWithArray(choices);
@@ -259,7 +251,7 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
}
if (pendingPresentOperation != null && !pendingPresentOperation.isCancelled() && !pendingPresentOperation.isDone() && (cellsToBeDeleted.retainAll(pendingPresentationChoices) || cellsToBeRemovedFromPending.retainAll(pendingPresentationChoices))){
- pendingPresentOperation.cancel(true);
+ pendingPresentOperation.cancel(false);
DebugTool.logWarning("Attempting to delete choice cells while there is a pending presentation operation. Pending presentation cancelled.");
pendingPresentOperation = null;
}
@@ -299,13 +291,16 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
*/
public void presentChoiceSet(@NonNull final ChoiceSet choiceSet, @Nullable final InteractionMode mode, @Nullable final KeyboardListener keyboardListener){
- if (!isReady()){ return; }
+ if (getState() == ERROR) {
+ DebugTool.logWarning("Choice Manager In Error State");
+ return;
+ }
// Perform additional checks against the ChoiceSet
if (!setUpChoiceSet(choiceSet)){ return; }
if (this.pendingPresentationSet != null && pendingPresentOperation != null){
- pendingPresentOperation.cancel(true);
+ pendingPresentOperation.cancel(false);
DebugTool.logWarning("Presenting a choice set while one is currently presented. Cancelling previous and continuing");
}
@@ -337,8 +332,6 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
if (pendingPresentationSet.getChoiceSetSelectionListener() != null){
pendingPresentationSet.getChoiceSetSelectionListener().onChoiceSelected(choiceCell, triggerSource,rowIndex);
}
- pendingPresentationSet = null;
- pendingPresentOperation = null;
}
@Override
@@ -346,8 +339,6 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
if (pendingPresentationSet.getChoiceSetSelectionListener() != null){
pendingPresentationSet.getChoiceSetSelectionListener().onError(error);
}
- pendingPresentationSet = null;
- pendingPresentOperation = null;
}
};
@@ -379,10 +370,13 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
return null;
}
- if (!isReady()){ return null; }
+ if (getState() == ERROR) {
+ DebugTool.logWarning("Choice Manager In Error State");
+ return null;
+ }
if (pendingPresentationSet != null && pendingPresentOperation != null){
- pendingPresentOperation.cancel(true);
+ pendingPresentOperation.cancel(false);
pendingPresentationSet = null;
DebugTool.logWarning("There is a current or pending choice set, cancelling and continuing.");
}
@@ -412,6 +406,11 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
* @param cancelID - The unique ID assigned to the keyboard, passed as the return value from `presentKeyboard`
*/
public void dismissKeyboard(@NonNull Integer cancelID) {
+ if (getState() == ERROR) {
+ DebugTool.logWarning("Choice Manager In Error State");
+ return;
+ }
+
// First, attempt to cancel the currently executing keyboard operation (Once an operation has started it is removed from the operationQueue)
if (currentlyPresentedKeyboardOperation != null && currentlyPresentedKeyboardOperation.getCancelID().equals(cancelID)) {
currentlyPresentedKeyboardOperation.dismissKeyboard();
@@ -537,10 +536,6 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
if (oldHMILevel == HMILevel.HMI_NONE && currentHMILevel != HMILevel.HMI_NONE){
executor.resume();
- if (waitingChoices != null && waitingChoices.size() > 0){
- DebugTool.logInfo("Pending Preload Choices now being sent");
- preloadChoices(waitingChoices, waitingListener);
- }
}
currentSystemContext = hmiStatus.getSystemContext();
@@ -551,10 +546,6 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
if (currentSystemContext == SystemContext.SYSCTXT_MAIN && currentHMILevel != HMILevel.HMI_NONE){
executor.resume();
- if (waitingChoices != null && waitingChoices.size() > 0){
- DebugTool.logInfo("Pending Preload Choices now being sent");
- preloadChoices(waitingChoices, waitingListener);
- }
}
}
@@ -624,13 +615,4 @@ abstract class BaseChoiceSetManager extends BaseSubManager {
defaultProperties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY);
return defaultProperties;
}
-
- @SuppressWarnings("BooleanMethodIsAlwaysInverted")
- boolean isReady(){
- if (getState() != READY){
- DebugTool.logWarning("Choice Manager In Not-Ready State");
- return false;
- }
- return true;
- }
}
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/CheckChoiceVROptionalOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/CheckChoiceVROptionalOperation.java
index 4ac5cb659..1c427c16b 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/CheckChoiceVROptionalOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/CheckChoiceVROptionalOperation.java
@@ -47,21 +47,24 @@ import com.smartdevicelink.util.DebugTool;
import java.lang.ref.WeakReference;
import java.util.Collections;
-class CheckChoiceVROptionalOperation implements Runnable {
+class CheckChoiceVROptionalOperation extends AsynchronousOperation {
private CheckChoiceVROptionalInterface checkChoiceVROptionalInterface;
private WeakReference<ISdl> internalInterface;
private boolean isVROptional;
CheckChoiceVROptionalOperation(ISdl internalInterface, CheckChoiceVROptionalInterface checkChoiceVROptionalInterface){
+ super();
this.internalInterface = new WeakReference<>(internalInterface);
this.checkChoiceVROptionalInterface = checkChoiceVROptionalInterface;
}
@Override
public void run() {
+ CheckChoiceVROptionalOperation.super.run();
DebugTool.logInfo("Choice Operation: Executing check vr optional operation");
sendTestChoiceNoVR();
+ block();
}
/**
@@ -117,6 +120,8 @@ class CheckChoiceVROptionalOperation implements Runnable {
if (checkChoiceVROptionalInterface != null){
checkChoiceVROptionalInterface.onError(response.getInfo());
}
+
+ CheckChoiceVROptionalOperation.super.finishOperation();
}
}
@@ -127,6 +132,8 @@ class CheckChoiceVROptionalOperation implements Runnable {
if (checkChoiceVROptionalInterface != null){
checkChoiceVROptionalInterface.onError(info);
}
+
+ CheckChoiceVROptionalOperation.super.finishOperation();
}
});
@@ -147,6 +154,8 @@ class CheckChoiceVROptionalOperation implements Runnable {
if (checkChoiceVROptionalInterface != null){
checkChoiceVROptionalInterface.onCheckChoiceVROperationComplete(isVROptional);
}
+
+ CheckChoiceVROptionalOperation.super.finishOperation();
}
@Override
@@ -155,6 +164,8 @@ class CheckChoiceVROptionalOperation implements Runnable {
if (checkChoiceVROptionalInterface != null){
checkChoiceVROptionalInterface.onError(info);
}
+
+ CheckChoiceVROptionalOperation.super.finishOperation();
}
});
if (internalInterface.get() != null){
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/DeleteChoicesOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/DeleteChoicesOperation.java
index fdb01ae38..2fc6c314d 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/DeleteChoicesOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/DeleteChoicesOperation.java
@@ -48,13 +48,14 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-class DeleteChoicesOperation implements Runnable {
+class DeleteChoicesOperation extends AsynchronousOperation {
private WeakReference<ISdl> internalInterface;
private HashSet<ChoiceCell> cellsToDelete;
private CompletionListener completionListener;
DeleteChoicesOperation(ISdl internalInterface, HashSet<ChoiceCell> cellsToDelete, CompletionListener completionListener){
+ super();
this.internalInterface = new WeakReference<>(internalInterface);
this.cellsToDelete = cellsToDelete;
this.completionListener = completionListener;
@@ -62,8 +63,10 @@ class DeleteChoicesOperation implements Runnable {
@Override
public void run() {
+ DeleteChoicesOperation.super.run();
DebugTool.logInfo("Choice Operation: Executing delete choices operation");
sendDeletions();
+ block();
}
private void sendDeletions(){
@@ -84,6 +87,8 @@ class DeleteChoicesOperation implements Runnable {
completionListener.onComplete(true);
}
DebugTool.logInfo("Successfully deleted choices");
+
+ DeleteChoicesOperation.super.finishOperation();
}
@Override
@@ -92,6 +97,8 @@ class DeleteChoicesOperation implements Runnable {
completionListener.onComplete(false);
}
DebugTool.logError("Failed to delete choice: " + info + " | Corr ID: " + correlationId);
+
+ DeleteChoicesOperation.super.finishOperation();
}
@Override
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperation.java
index f3d708998..99cd91a96 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PreloadChoicesOperation.java
@@ -62,7 +62,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
-class PreloadChoicesOperation implements Runnable {
+class PreloadChoicesOperation extends AsynchronousOperation {
private WeakReference<ISdl> internalInterface;
private WeakReference<FileManager> fileManager;
@@ -74,6 +74,7 @@ class PreloadChoicesOperation implements Runnable {
PreloadChoicesOperation(ISdl internalInterface, FileManager fileManager, DisplayCapabilities displayCapabilities,
Boolean isVROptional, HashSet<ChoiceCell> cellsToPreload, CompletionListener listener){
+ super();
this.internalInterface = new WeakReference<>(internalInterface);
this.fileManager = new WeakReference<>(fileManager);
this.displayCapabilities = displayCapabilities;
@@ -84,6 +85,7 @@ class PreloadChoicesOperation implements Runnable {
@Override
public void run() {
+ PreloadChoicesOperation.super.run();
DebugTool.logInfo("Choice Operation: Executing preload choices operation");
preloadCellArtworks(new CompletionListener() {
@Override
@@ -91,6 +93,7 @@ class PreloadChoicesOperation implements Runnable {
preloadCells();
}
});
+ block();
}
void removeChoicesFromUpload(HashSet<ChoiceCell> choices){
@@ -161,11 +164,15 @@ class PreloadChoicesOperation implements Runnable {
isRunning = false;
DebugTool.logInfo("Finished pre loading choice cells");
completionListener.onComplete(true);
+
+ PreloadChoicesOperation.super.finishOperation();
}
@Override
public void onError(int correlationId, Result resultCode, String info) {
DebugTool.logError("There was an error uploading a choice cell: "+ info + " resultCode: " + resultCode);
+
+ PreloadChoicesOperation.super.finishOperation();
}
@Override
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 40672a2df..af69c0926 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
@@ -103,6 +103,7 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
DebugTool.logInfo("Choice Operation: Executing present choice set operation");
addListeners();
start();
+ block();
}
private void start(){
@@ -162,8 +163,10 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
@Override
public void onError(int correlationId, Result resultCode, String info) {
+ if (listener != null){
+ listener.onComplete(false);
+ }
DebugTool.logError("Error Setting keyboard properties in present keyboard operation - choice manager - " + info);
- super.onError(correlationId, resultCode, info);
}
});
if (internalInterface.get() != null){
@@ -197,6 +200,16 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
finishOperation();
}
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {
+ DebugTool.logError("Presenting Choice set failed: " + resultCode + ", " + info);
+
+ if (choiceSetSelectionListener != null){
+ choiceSetSelectionListener.onError(resultCode + ", " + info);
+ }
+ finishOperation();
+ }
});
if (internalInterface.get() != null){
internalInterface.get().sendRPC(pi);
@@ -217,6 +230,12 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
DebugTool.logInfo("Successfully reset choice keyboard properties to original config");
PresentChoiceSetOperation.super.finishOperation();
}
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {
+ DebugTool.logError("Failed to reset choice keyboard properties to original config " + resultCode + ", " + info);
+ PresentChoiceSetOperation.super.finishOperation();
+ }
});
if (internalInterface.get() != null) {
@@ -268,7 +287,7 @@ class PresentChoiceSetOperation extends AsynchronousOperation {
}
} else {
DebugTool.logInfo("Canceling a choice set that has not yet been sent to Core");
- Thread.currentThread().interrupt();
+ this.cancel();
}
}
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperation.java
index 188016129..5089d0c92 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperation.java
@@ -71,6 +71,7 @@ class PresentKeyboardOperation extends AsynchronousOperation {
SdlMsgVersion sdlMsgVersion;
PresentKeyboardOperation(ISdl internalInterface, KeyboardProperties originalKeyboardProperties, String initialText, KeyboardProperties customConfig, KeyboardListener keyboardListener, Integer cancelID){
+ super();
this.internalInterface = new WeakReference<>(internalInterface);
this.keyboardListener = keyboardListener;
this.originalKeyboardProperties = originalKeyboardProperties;
@@ -87,6 +88,7 @@ class PresentKeyboardOperation extends AsynchronousOperation {
DebugTool.logInfo("Keyboard Operation: Executing present keyboard operation");
addListeners();
start();
+ block();
}
private void start(){
@@ -179,7 +181,7 @@ class PresentKeyboardOperation extends AsynchronousOperation {
}
} else {
DebugTool.logInfo("Canceling a keyboard that has not yet been sent to Core.");
- Thread.currentThread().interrupt();
+ this.cancel();
}
}
@@ -215,6 +217,9 @@ class PresentKeyboardOperation extends AsynchronousOperation {
@Override
public void onError(int correlationId, Result resultCode, String info) {
+ if (listener != null){
+ listener.onComplete(false);
+ }
DebugTool.logError("Error Setting keyboard properties in present keyboard operation - choice manager - " + info);
super.onError(correlationId, resultCode, info);
}
@@ -239,6 +244,12 @@ class PresentKeyboardOperation extends AsynchronousOperation {
DebugTool.logInfo("Successfully reset choice keyboard properties to original config");
PresentKeyboardOperation.super.finishOperation();
}
+
+ @Override
+ public void onError(int correlationId, Result resultCode, String info) {
+ DebugTool.logError("Failed to reset choice keyboard properties to original config " + resultCode + ", " + info);
+ PresentKeyboardOperation.super.finishOperation();
+ }
});
if (internalInterface.get() != null) {