diff options
13 files changed, 1661 insertions, 0 deletions
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCellTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCellTests.java new file mode 100644 index 000000000..7d1108aff --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCellTests.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import com.smartdevicelink.AndroidTestCase2; +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.proxy.rpc.enums.FileType; +import com.smartdevicelink.test.Test; + +public class ChoiceCellTests extends AndroidTestCase2 { + + private static final int MAX_ID = 2000000000; + private SdlArtwork artwork = new SdlArtwork("image", FileType.GRAPHIC_PNG, 1, true); + + @Override + public void setUp() throws Exception{ + super.setUp(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + } + + public void testSettersAndGetters(){ + + // set everything + ChoiceCell choiceCell = new ChoiceCell(Test.GENERAL_STRING); + choiceCell.setSecondaryText(Test.GENERAL_STRING); + choiceCell.setTertiaryText(Test.GENERAL_STRING); + choiceCell.setVoiceCommands(Test.GENERAL_STRING_LIST); + choiceCell.setArtwork(artwork); + choiceCell.setSecondaryArtwork(artwork); + + + // use getters and assert equality + assertEquals(choiceCell.getText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getSecondaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getTertiaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getVoiceCommands(), Test.GENERAL_STRING_LIST); + assertEquals(choiceCell.getArtwork(), artwork); + assertEquals(choiceCell.getSecondaryArtwork(), artwork); + assertEquals(choiceCell.getChoiceId(), MAX_ID); + } + + public void testConstructors() { + // first constructor was tested in previous method, use the rest here + + ChoiceCell choiceCell = new ChoiceCell(Test.GENERAL_STRING, Test.GENERAL_STRING_LIST, artwork); + choiceCell.setSecondaryText(Test.GENERAL_STRING); + choiceCell.setTertiaryText(Test.GENERAL_STRING); + choiceCell.setSecondaryArtwork(artwork); + assertEquals(choiceCell.getText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getSecondaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getTertiaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getVoiceCommands(), Test.GENERAL_STRING_LIST); + assertEquals(choiceCell.getArtwork(), artwork); + assertEquals(choiceCell.getSecondaryArtwork(), artwork); + assertEquals(choiceCell.getChoiceId(), MAX_ID); + + + choiceCell = new ChoiceCell(Test.GENERAL_STRING, Test.GENERAL_STRING, Test.GENERAL_STRING, Test.GENERAL_STRING_LIST, artwork, artwork); + assertEquals(choiceCell.getText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getSecondaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getTertiaryText(), Test.GENERAL_STRING); + assertEquals(choiceCell.getVoiceCommands(), Test.GENERAL_STRING_LIST); + assertEquals(choiceCell.getArtwork(), artwork); + assertEquals(choiceCell.getSecondaryArtwork(), artwork); + assertEquals(choiceCell.getChoiceId(), MAX_ID); + } + + public void testCellEquality(){ + + ChoiceCell choiceCell = new ChoiceCell(Test.GENERAL_STRING, Test.GENERAL_STRING_LIST, artwork); + choiceCell.setSecondaryText(Test.GENERAL_STRING); + choiceCell.setTertiaryText(Test.GENERAL_STRING); + choiceCell.setSecondaryArtwork(artwork); + + ChoiceCell choiceCell2 = new ChoiceCell(Test.GENERAL_STRING, Test.GENERAL_STRING_LIST, artwork); + choiceCell2.setSecondaryText(Test.GENERAL_STRING); + choiceCell2.setTertiaryText(Test.GENERAL_STRING); + choiceCell2.setSecondaryArtwork(artwork); + + ChoiceCell choiceCell3 = new ChoiceCell(Test.GENERAL_STRING, Test.GENERAL_STRING_LIST, artwork); + choiceCell3.setSecondaryText(Test.GENERAL_STRING); + choiceCell3.setTertiaryText(Test.GENERAL_STRING); + + // Make sure our overridden method works, even though these are different objects in memory + assertTrue(choiceCell.equals(choiceCell2)); + assertFalse(choiceCell.equals(choiceCell3)); + + } +} diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayoutTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayoutTests.java new file mode 100644 index 000000000..3f147f128 --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayoutTests.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import com.smartdevicelink.AndroidTestCase2; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ChoiceSetLayoutTests extends AndroidTestCase2 { + /** + * Verifies that the enum values are not null upon valid assignment. + */ + public void testValidEnums() { + ChoiceSetLayout choiceSetLayoutList = ChoiceSetLayout.valueForString("CHOICE_SET_LAYOUT_LIST"); + ChoiceSetLayout choiceSetLayoutTiles = ChoiceSetLayout.valueForString("CHOICE_SET_LAYOUT_TILES"); + assertNotNull("CHOICE_SET_LAYOUT_LIST returned null", choiceSetLayoutList); + assertNotNull("choiceSetLayoutTiles returned null", choiceSetLayoutTiles); + } + + /** + * Verifies that an invalid assignment is null. + */ + public void testInvalidEnum() { + String example = "deFaUlt"; + try { + ChoiceSetLayout temp = ChoiceSetLayout.valueForString(example); + assertNull("Result of valueForString should be null.", temp); + } catch (IllegalArgumentException exception) { + fail("Invalid enum throws IllegalArgumentException."); + } + } + + /** + * Verifies that a null assignment is invalid. + */ + public void testNullEnum() { + String example = null; + try { + ChoiceSetLayout temp = ChoiceSetLayout.valueForString(example); + assertNull("Result of valueForString should be null.", temp); + } catch (NullPointerException exception) { + fail("Null string throws NullPointerException."); + } + } + + /** + * Verifies the possible enum values of DynamicMenuUpdatesMode. + */ + public void testListEnum() { + List<ChoiceSetLayout> enumValueList = Arrays.asList(ChoiceSetLayout.values()); + + List<ChoiceSetLayout> enumTestList = new ArrayList<>(); + enumTestList.add(ChoiceSetLayout.CHOICE_SET_LAYOUT_LIST); + enumTestList.add(ChoiceSetLayout.CHOICE_SET_LAYOUT_TILES); + + + assertTrue("Enum value list does not match enum class list", + enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList)); + } +} diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java new file mode 100644 index 000000000..78b68f2a2 --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetTests.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import com.smartdevicelink.AndroidTestCase2; +import com.smartdevicelink.test.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.mockito.Mockito.mock; + +public class ChoiceSetTests extends AndroidTestCase2 { + + private ChoiceSetSelectionListener listener; + private ChoiceSetLayout layout; + private List<ChoiceCell> choices; + private Integer defaultTimeout; + + @Override + public void setUp() throws Exception{ + super.setUp(); + + listener = mock(ChoiceSetSelectionListener.class); + layout = ChoiceSetLayout.CHOICE_SET_LAYOUT_LIST; + defaultTimeout = 10; + choices = Arrays.asList(new ChoiceCell(Test.GENERAL_STRING), new ChoiceCell(Test.GENERAL_STRING)); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + } + + public void testSettersAndGetters(){ + + // test small constructor + ChoiceSet choiceSet = new ChoiceSet(Test.GENERAL_STRING, listener, choices); + + // use getters and assert equality + assertEquals(choiceSet.getTitle(), Test.GENERAL_STRING); + assertEquals(choiceSet.getLayout(), layout); + assertEquals(choiceSet.getTimeout(), defaultTimeout); + assertEquals(choiceSet.getChoices(), choices); + assertEquals(choiceSet.getChoiceSetSelectionListener(), listener); + } + + public void testConstructors() { + + // first constructor was tested in previous method, use the rest here + ChoiceSet choiceSet = new ChoiceSet(Test.GENERAL_STRING, listener, layout, Test.GENERAL_INTEGER, Test.GENERAL_STRING, Test.GENERAL_STRING, Test.GENERAL_STRING, Test.GENERAL_VRHELPITEM_LIST, choices); + assertEquals(choiceSet.getTitle(), Test.GENERAL_STRING); + assertEquals(choiceSet.getInitialPrompt().get(0).getText(),Test.GENERAL_STRING); + assertEquals(choiceSet.getHelpPrompt().get(0).getText(), Test.GENERAL_STRING); + assertEquals(choiceSet.getTimeoutPrompt().get(0).getText(), Test.GENERAL_STRING); + assertEquals(choiceSet.getLayout(), layout); + assertEquals(choiceSet.getTimeout(), Test.GENERAL_INTEGER); + assertEquals(choiceSet.getChoices(), choices); + assertEquals(choiceSet.getChoiceSetSelectionListener(), listener); + + ChoiceSet choiceSet2 = new ChoiceSet(Test.GENERAL_STRING, listener, layout, Test.GENERAL_INTEGER, Test.GENERAL_TTSCHUNK_LIST, Test.GENERAL_TTSCHUNK_LIST, Test.GENERAL_TTSCHUNK_LIST, Test.GENERAL_VRHELPITEM_LIST, choices); + assertEquals(choiceSet2.getTitle(), Test.GENERAL_STRING); + assertEquals(choiceSet2.getInitialPrompt(),Test.GENERAL_TTSCHUNK_LIST); + assertEquals(choiceSet2.getHelpPrompt(), Test.GENERAL_TTSCHUNK_LIST); + assertEquals(choiceSet2.getTimeoutPrompt(), Test.GENERAL_TTSCHUNK_LIST); + assertEquals(choiceSet2.getLayout(), layout); + assertEquals(choiceSet2.getTimeout(), Test.GENERAL_INTEGER); + assertEquals(choiceSet2.getChoices(), choices); + assertEquals(choiceSet2.getChoiceSetSelectionListener(), listener); + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java new file mode 100644 index 000000000..2cb3ad2f3 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.proxy.interfaces.ISdl; + +/** + * <strong>ChoiceSetManager</strong> <br> + * ChoiceSetManager gives the developer the ability to control how soft choice sets are displayed on the head unit.<br> + * Note: This class must be accessed through the SdlManager->ScreenManager. Do not instantiate it by itself.<br> + */ +class ChoiceSetManager extends BaseChoiceSetManager { + + /** + * Creates a new instance of the ChoiceSetManager + * + * @param internalInterface + */ + ChoiceSetManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager) { + super(internalInterface, fileManager); + } +} 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 new file mode 100644 index 000000000..1010eefc4 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.BaseSubManager; +import com.smartdevicelink.managers.CompletionListener; +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.RPCNotification; +import com.smartdevicelink.proxy.interfaces.ISdl; +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.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.InteractionMode; +import com.smartdevicelink.proxy.rpc.enums.KeyboardLayout; +import com.smartdevicelink.proxy.rpc.enums.KeypressMode; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import com.smartdevicelink.util.DebugTool; + +import java.lang.ref.WeakReference; +import java.util.HashSet; +import java.util.List; + +/** + * <strong>ChoiceSetManager</strong> <br> + * <p> + * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br> + */ +public abstract class BaseChoiceSetManager extends BaseSubManager { + + // additional state + private static final int CHECKING_VOICE = 0xA0; + + OnRPCNotificationListener hmiListener; + OnSystemCapabilityListener displayListener; + + private final WeakReference<FileManager> fileManager; + private KeyboardProperties keyboardConfiguration; + private HMILevel currentHMILevel; + private SystemContext currentSystemContext; + private DisplayCapabilities displayCapabilities; + + private HashSet<ChoiceCell> preloadedChoices; + private HashSet<ChoiceCell> pendingPreloadChoices; + private HashSet<ChoiceCell> preloadedMutableChoices; + private HashSet<ChoiceCell> pendingMutablePreloadChoices; + private ChoiceSet pendingPresentationSet; + private Boolean isVROptional; + + private int nextChoiceId; + private int choiceCellIdMin = 1; + + public BaseChoiceSetManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager) { + super(internalInterface); + + transitionToState(SHUTDOWN); // We need to do some stuff first. keep in shutdown state + this.fileManager = new WeakReference<>(fileManager); + preloadedMutableChoices = new HashSet<>(); + pendingMutablePreloadChoices = new HashSet<>(); + nextChoiceId = choiceCellIdMin; + isVROptional = true; + keyboardConfiguration = defaultKeyboardConfiguration(); + addListeners(); + } + + @Override + public void start(CompletionListener listener){ + if (getState() == SHUTDOWN) { + transitionToState(SETTING_UP); + checkVoiceOptional(); + super.start(listener); + } // Else we are already started + } + + @Override + public void dispose(){ + + currentHMILevel = null; + currentSystemContext = null; + displayCapabilities = null; + + // TODO: cancel all queued operations, if any exist + + pendingPresentationSet = null; + isVROptional = true; + nextChoiceId = choiceCellIdMin; + + super.dispose(); + } + + public void preloadChoices(List<ChoiceCell> choices, CompletionListener listener){ + if (getState() != READY){ return; } + + HashSet<ChoiceCell> choicesToUpload = choicesToBeUploadedWithArray(choices); + choicesToUpload.removeAll(preloadedMutableChoices); + choicesToUpload.removeAll(pendingMutablePreloadChoices); + + if (choicesToUpload.size() == 0){ + if (listener != null){ + listener.onComplete(true); + } + return; + } + + updateIdsOnChoices(choicesToUpload); + + // Add the preload cells to the pending preload choices + pendingMutablePreloadChoices.addAll(choicesToUpload); + + // Upload pending preloads + + //TODO: PreloadChoicesOperation + + } + + public void deleteChoices(List<ChoiceCell> choices){ + if (getState() != READY){ return; } + + // Find cells to be deleted that are already uploaded or are pending upload + HashSet<ChoiceCell> cellsToDelete = choicesToBeDeletedWithArray(choices); + HashSet<ChoiceCell> cellsToBeRemovedFromPending = choicesToBeRemovedFromPendingWithArray(choices); + + // If choices are deleted that are already uploaded or pending and are used by a pending presentation, cancel it and send an error + if (pendingPresentationSet != null && pendingPresentationSet.getChoices() != null) { + HashSet<ChoiceCell> pendingPresentationChoices = new HashSet<>(pendingPresentationSet.getChoices()); + + } + + } + + public void presentChoiceSet(final ChoiceSet choiceSet, InteractionMode mode, KeyboardListener listener){ + if (getState() != READY){ return; } + if (choiceSet == null) { + DebugTool.logWarning("Attempted to present a null choice set. Ignoring request"); + return; + } + // Perform additional checks against the ChoiceSet + if (!setUpChoiceSet(choiceSet)){ return; } + + if (this.pendingPresentationSet != null){ + // cancel pendingPresentationOperation + } + + this.pendingPresentationSet = choiceSet; + preloadChoices(this.pendingPresentationSet.getChoices(), new CompletionListener() { + @Override + public void onComplete(boolean success) { + if (!success){ + choiceSet.getChoiceSetSelectionListener().onError("There was an error pre-loading choice set choices"); + return; + } + } + }); + + findIdsOnChoiceSet(this.pendingPresentationSet); + + // create presentationChoiceSetOperation + // add the operation to the queue + + } + + public void presentKeyboardWithInitialText(String initialText, KeyboardListener listener){ + if (getState() != READY){ return; } + + if (pendingPresentationSet != null){ + //[self.pendingPresentOperation cancel]; + pendingPresentationSet = null; + } + + // create PresentKeyboardOperation + // add operation to the transaction queue + } + + // SETTERS + + public void setKeyboardConfiguration(KeyboardProperties keyboardConfiguration){ + + if (keyboardConfiguration == null){ + this.keyboardConfiguration = defaultKeyboardConfiguration(); + } else{ + KeyboardProperties properties = new KeyboardProperties(); + properties.setLanguage((keyboardConfiguration.getLanguage() == null ? Language.EN_US : keyboardConfiguration.getLanguage())); + properties.setKeyboardLayout((keyboardConfiguration.getKeyboardLayout() == null ? KeyboardLayout.QWERTZ : keyboardConfiguration.getKeyboardLayout())); + properties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY); + properties.setLimitedCharacterList(keyboardConfiguration.getLimitedCharacterList()); + properties.setAutoCompleteText(keyboardConfiguration.getAutoCompleteText()); + this.keyboardConfiguration = properties; + } + } + + // GETTERS + + public HashSet<ChoiceCell> getPreloadedChoices(){ + return this.preloadedChoices; + } + + public HashSet<ChoiceCell> getPendingPreloadChoices(){ + return this.pendingPreloadChoices; + } + + // CHOICE SET MANAGEMENT HELPERS + + private HashSet<ChoiceCell> choicesToBeUploadedWithArray(List<ChoiceCell> choices){ + HashSet<ChoiceCell> choicesSet = new HashSet<>(choices); + choicesSet.removeAll(this.preloadedChoices); + return choicesSet; + } + + private HashSet<ChoiceCell> choicesToBeDeletedWithArray(List<ChoiceCell> choices){ + HashSet<ChoiceCell> choicesSet = new HashSet<>(choices); + choicesSet.retainAll(this.preloadedChoices); + return choicesSet; + } + + private HashSet<ChoiceCell> choicesToBeRemovedFromPendingWithArray(List<ChoiceCell> choices){ + HashSet<ChoiceCell> choicesSet = new HashSet<>(choices); + choicesSet.retainAll(this.pendingPreloadChoices); + return choicesSet; + } + + private void updateIdsOnChoices(HashSet<ChoiceCell> choices){ + for (ChoiceCell cell : choices){ + cell.setChoiceId(this.nextChoiceId); + this.nextChoiceId++; + } + } + + private void findIdsOnChoiceSet(ChoiceSet choiceSet){ + findIdsOnChoices(new HashSet<>(choiceSet.getChoices())); + } + + private void findIdsOnChoices(HashSet<ChoiceCell> choices){ + for (ChoiceCell cell : choices){ + ChoiceCell uploadCell = null; + if (pendingPreloadChoices.contains(cell)){ + uploadCell = findIfPresent(cell, pendingPreloadChoices); + }else if (preloadedChoices.contains(cell)){ + uploadCell = findIfPresent(cell, preloadedChoices); + } + if (uploadCell != null ){ + cell.setChoiceId(uploadCell.getChoiceId()); + } + } + } + + private ChoiceCell findIfPresent(ChoiceCell cell, HashSet<ChoiceCell> set){ + if (set.contains(cell)) { + for (ChoiceCell setCell : set) { + if (setCell.equals(cell)) + return setCell; + } + } + return null; + } + + // LISTENERS + + private void addListeners(){ + + // DISPLAY CAPABILITIES - via SCM + displayListener = new OnSystemCapabilityListener() { + @Override + public void onCapabilityRetrieved(Object capability) { + displayCapabilities = (DisplayCapabilities) capability; + } + + @Override + public void onError(String info) { + DebugTool.logError("Unable to retrieve display capabilities. Many things will probably break. Info: "+ info); + } + }; + internalInterface.getCapability(SystemCapabilityType.DISPLAY, displayListener); + + // HMI UPDATES + hmiListener = new OnRPCNotificationListener() { + @Override + public void onNotified(RPCNotification notification) { + OnHMIStatus hmiStatus = (OnHMIStatus) notification; + HMILevel oldHMILevel = currentHMILevel; + currentHMILevel = hmiStatus.getHmiLevel(); + } + }; + internalInterface.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, hmiListener); + + } + + // ADDITIONAL HELPERS + + private void checkVoiceOptional(){ + transitionToState(CHECKING_VOICE); + + // TODO: CheckChoiceVROptionalOperation + } + + private boolean setUpChoiceSet(ChoiceSet choiceSet) { + + List<ChoiceCell> choices = choiceSet.getChoices(); + + // Choices are not optional here + if (choices == null) { + DebugTool.logError("Cannot initiate a choice set with no choices"); + return false; + } + + HashSet<String> choiceTextSet = new HashSet<>(); + HashSet<String> uniqueVoiceCommands = new HashSet<>(); + int allVoiceCommandsCount = 0; + int choiceCellWithVoiceCommandCount = 0; + + for (ChoiceCell cell : choices) { + + choiceTextSet.add(cell.getText()); + + if (cell.getVoiceCommands() != null) { + uniqueVoiceCommands.addAll(cell.getVoiceCommands()); + choiceCellWithVoiceCommandCount += 1; + allVoiceCommandsCount += cell.getVoiceCommands().size(); + } + } + + // Cell text MUST be unique + if (choiceTextSet.size() < choices.size()) { + DebugTool.logError("Attempted to create a choice set with duplicate cell text. Cell text must be unique. The choice set will not be set."); + return false; + } + + // All or none of the choices MUST have VR Commands + if (choiceCellWithVoiceCommandCount > 0 && choiceCellWithVoiceCommandCount < choices.size()) { + DebugTool.logError("If using voice recognition commands, all of the choice set cells must have unique VR commands. There are " + uniqueVoiceCommands.size() + " cells with unique voice commands and " + allVoiceCommandsCount + " total cells. The choice set will not be set."); + return false; + } + + // All VR Commands MUST be unique + if (uniqueVoiceCommands.size() < allVoiceCommandsCount) { + DebugTool.logError("If using voice recognition commands, all VR commands must be unique. There are " + uniqueVoiceCommands.size() + " unique VR commands and " + allVoiceCommandsCount + " VR commands. The choice set will not be set."); + return false; + } + + return true; + } + + + private KeyboardProperties defaultKeyboardConfiguration(){ + KeyboardProperties defaultProperties = new KeyboardProperties(); + defaultProperties.setLanguage(Language.EN_US); + defaultProperties.setKeyboardLayout(KeyboardLayout.QWERTY); + defaultProperties.setKeypressMode(KeypressMode.RESEND_CURRENT_ENTRY); + return defaultProperties; + } +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCell.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCell.java new file mode 100644 index 000000000..136ee0741 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceCell.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; + +import java.util.List; + +public class ChoiceCell { + private String text, secondaryText, tertiaryText; + private List<String> voiceCommands; + private SdlArtwork artwork, secondaryArtwork; + private Integer choiceId; + + /** + * MAX ID for cells - Cannot use Integer.MAX_INT as the value is too high. + */ + private static final int MAX_ID = 2000000000; + + /** + * Initialize the cell with text and nothing else. + * + * @param text - The primary text of the cell. + */ + public ChoiceCell(@NonNull String text) { + setText(text); + setChoiceId(MAX_ID); + } + + /** + * Initialize the cell with text, optional artwork, and optional voice commands + * + * @param text - The primary text of the cell + * @param voiceCommands - Strings that can be spoken by the user to activate this cell in a voice or both interaction mode + * @param artwork - The primary artwork of the cell + */ + public ChoiceCell(@NonNull String text, List<String> voiceCommands, SdlArtwork artwork) { + setText(text); + setVoiceCommands(voiceCommands); + setArtwork(artwork); + setChoiceId(MAX_ID); + } + + /** + * Initialize the cell with all optional items + * + * @param text - The primary text + * @param secondaryText - The secondary text + * @param tertiaryText - The tertiary text + * @param voiceCommands - Strings that can be spoken by the user to activate this cell in a voice or both interaction mode + * @param artwork - The primary artwork of the cell + * @param secondaryArtwork - The secondary artwork of the cell + */ + public ChoiceCell(@NonNull String text, String secondaryText, String tertiaryText, List<String> voiceCommands, SdlArtwork artwork, SdlArtwork secondaryArtwork) { + setText(text); + setSecondaryText(secondaryText); + setTertiaryText(tertiaryText); + setVoiceCommands(voiceCommands); + setArtwork(artwork); + setSecondaryArtwork(secondaryArtwork); + setChoiceId(MAX_ID); + } + + /** + * Maps to Choice.menuName. The primary text of the cell. Duplicates within an `ChoiceSet` + * are not permitted and will result in the `ChoiceSet` failing to initialize. + * @return The primary text of the cell + */ + public String getText() { + return text; + } + + /** + * @param text - Maps to Choice.menuName. The primary text of the cell. Duplicates within an `ChoiceSet` + * are not permitted and will result in the `ChoiceSet` failing to initialize. + */ + public void setText(@NonNull String text) { + this.text = text; + } + + /** + * Maps to Choice.secondaryText. Optional secondary text of the cell, if available. Duplicates + * within an `ChoiceSet` are permitted. + * @return Optional secondary text of the cell + */ + public String getSecondaryText() { + return secondaryText; + } + + /** + * @param secondaryText - Maps to Choice.secondaryText. Optional secondary text of the cell, if + * available. Duplicates within an `ChoiceSet` are permitted. + */ + public void setSecondaryText(String secondaryText) { + this.secondaryText = secondaryText; + } + + /** + * Maps to Choice.tertiaryText. Optional tertiary text of the cell, if available. Duplicates within an `ChoiceSet` are permitted. + * @return Optional tertiary text of the cell + */ + public String getTertiaryText() { + return tertiaryText; + } + + /** + * @param tertiaryText - Maps to Choice.tertiaryText. Optional tertiary text of the cell, if + * available. Duplicates within an `ChoiceSet` are permitted. + */ + public void setTertiaryText(String tertiaryText) { + this.tertiaryText = tertiaryText; + } + + /** + * Maps to Choice.vrCommands. Optional voice commands the user can speak to activate the cell. + * If not set and the head unit requires it, this will be set to the number in the list that this + * item appears. However, this would be a very poor experience for a user if the choice set is + * presented as a voice only interaction or both interaction mode. Therefore, consider not setting + * this only when you know the choice set will be presented as a touch only interaction. + * @return The list of voice command strings + */ + public List<String> getVoiceCommands() { + return voiceCommands; + } + + /** + * @param voiceCommands - Maps to Choice.vrCommands. Optional voice commands the user can speak to activate the cell. + * If not set and the head unit requires it, this will be set to the number in the list that this + * item appears. However, this would be a very poor experience for a user if the choice set is + * presented as a voice only interaction or both interaction mode. Therefore, consider not setting + * this only when you know the choice set will be presented as a touch only interaction. + */ + public void setVoiceCommands(List<String> voiceCommands) { + this.voiceCommands = voiceCommands; + } + + /** + * Maps to Choice.image. Optional image for the cell. This will be uploaded before the cell is + * used when the cell is preloaded or presented for the first time. + * @return The SdlArtwork + */ + public SdlArtwork getArtwork() { + return artwork; + } + + /** + * @param artwork - Maps to Choice.image. Optional image for the cell. This will be uploaded + * before the cell is used when the cell is preloaded or presented for the first time. + */ + public void setArtwork(SdlArtwork artwork) { + this.artwork = artwork; + } + + /** + * Maps to Choice.secondaryImage. Optional secondary image for the cell. This will be uploaded + * before the cell is used when the cell is preloaded or presented for the first time. + * @return The SdlArtwork + */ + public SdlArtwork getSecondaryArtwork() { + return secondaryArtwork; + } + + /** + * @param secondaryArtwork - Maps to Choice.secondaryImage. Optional secondary image for the cell. + * This will be uploaded before the cell is used when the cell is preloaded or presented for the first time. + */ + public void setSecondaryArtwork(SdlArtwork secondaryArtwork) { + this.secondaryArtwork = secondaryArtwork; + } + + /** + * NOTE: USED INTERNALLY + * Set the choice Id. + * @param choiceId - the choice Id + */ + void setChoiceId(int choiceId) { + this.choiceId = choiceId; + } + + /** + * NOTE: USED INTERNALLY + * Get the choiceId + * @return the choiceId for this Choice Cell + */ + int getChoiceId() { + return choiceId; + } + + @Override + public int hashCode() { + int result = 1; + result += ((getText() == null) ? 0 : Integer.rotateLeft(getText().hashCode(), 1)); + result += ((getSecondaryText() == null) ? 0 : Integer.rotateLeft(getSecondaryText().hashCode(), 2)); + result += ((getTertiaryText() == null) ? 0 : Integer.rotateLeft(getTertiaryText().hashCode(), 3)); + result += ((getArtwork() == null || getArtwork().getName() == null) ? 0 : Integer.rotateLeft(getArtwork().getName().hashCode(), 4)); + result += ((getSecondaryArtwork() == null || getSecondaryArtwork().getName() == null) ? 0 : Integer.rotateLeft(getSecondaryArtwork().getName().hashCode(), 5)); + result += ((getVoiceCommands() == null) ? 0 : Integer.rotateLeft(getVoiceCommands().hashCode(), 6)); + return result; + } + + /** + * Uses our custom hashCode for ChoiceCell objects + * @param o - The object to compare + * @return boolean of whether the objects are the same or not + */ + @Override + public boolean equals(Object o) { + // if this is the same memory address, its the same + if (this == o) return true; + // if this is not an instance of this class, not the same + if (!(o instanceof ChoiceCell)) return false; + + ChoiceCell choiceCell = (ChoiceCell) o; + // if we get to this point, create the hashes and compare them + return hashCode() == choiceCell.hashCode(); + } + + /** + * Overriding toString was throwing a warning in AS, so I changed the name for now + * @return A string description of the cell, useful for debugging. + */ + public String getDescription() { + return "ChoiceCell: ID: " + this.choiceId + " Text: " + text+ " - "+ secondaryText+" - "+ " - "+ tertiaryText+ " " + + "| Artwork Names: "+ ((getArtwork() == null || getArtwork().getName() == null) ? "Primary Art null" : getArtwork().getName()) + + " - "+((getSecondaryArtwork() == null || getSecondaryArtwork().getName() == null) ? "Secondary Art null" : getSecondaryArtwork().getName()) + + " Voice Commands Size: "+ ((getVoiceCommands() == null) ? 0 : getVoiceCommands().size()); + } + +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSet.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSet.java new file mode 100644 index 000000000..335fddf9f --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSet.java @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import com.smartdevicelink.exception.SdlException; +import com.smartdevicelink.exception.SdlExceptionCause; +import com.smartdevicelink.proxy.TTSChunkFactory; +import com.smartdevicelink.proxy.rpc.TTSChunk; +import com.smartdevicelink.proxy.rpc.VrHelpItem; +import com.smartdevicelink.util.DebugTool; + +import java.util.HashSet; +import java.util.List; + +public class ChoiceSet { + private String title; + private List<TTSChunk> initialPrompt, timeoutPrompt, helpPrompt; + private ChoiceSetLayout layout; + private Integer timeout; + private List<ChoiceCell> choices; + private List<VrHelpItem> vrHelpList; + private ChoiceSetSelectionListener choiceSetSelectionListener; + + // defaults + private Integer defaultTimeout = 10; + private ChoiceSetLayout defaultLayout = ChoiceSetLayout.CHOICE_SET_LAYOUT_LIST; + + /** + * Initialize with a title, listener, and choices. It will use the default timeout and layout, + * all other properties (such as prompts) will be `null`. + * + * @param title - The choice set's title + * @param listener - The choice set listener called after the user has interacted with your choice set + * @param choices - The choices to be displayed to the user for interaction + */ + public ChoiceSet(@NonNull String title, @NonNull ChoiceSetSelectionListener listener, @NonNull List<ChoiceCell> choices) { + + setTitle(title); + setChoiceSetSelectionListener(listener); + setChoices(choices); + + // defaults + setLayout(defaultLayout); + setTimeout(defaultTimeout); + + // things to do + checkChoiceSetParameters(); + } + + /** + * Constructor with all possible properties. + * + * @param title - The choice set's title + * @param listener - The choice set listener called after the user has interacted with your choice set + * @param layout - The layout of choice options (Manual/touch only) + * @param timeout - The timeout of a touch interaction (Manual/touch only) + * @param initialPrompt - A voice prompt spoken to the user when this set is displayed + * @param timeoutPrompt - A voice prompt spoken to the user when the set times out (Voice only) + * @param helpPrompt - A voice prompt spoken to the user when the user asks for "help" + * @param helpList - A table list of text and images shown to the user during a voice recognition session for this choice set (Voice only) + * @param choices - The list of choices presented to the user either as a manual/touch interaction or via the user's voice + */ + public ChoiceSet(@NonNull String title, @NonNull ChoiceSetSelectionListener listener, @Nullable ChoiceSetLayout layout, @Nullable Integer timeout, @Nullable String initialPrompt, @Nullable String timeoutPrompt, @Nullable String helpPrompt, @Nullable List<VrHelpItem> helpList, @NonNull List<ChoiceCell> choices) { + + setTitle(title); + setChoiceSetSelectionListener(listener); + setLayout(layout); + setTimeout(timeout); + setChoices(choices); + + // Help the dev by creating TTS chunks for them + if (initialPrompt != null){ + setInitialPrompt(TTSChunkFactory.createSimpleTTSChunks(initialPrompt)); + } + + if (timeoutPrompt != null){ + setTimeoutPrompt(TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt)); + } + + if (helpPrompt != null){ + setHelpPrompt(TTSChunkFactory.createSimpleTTSChunks(helpPrompt)); + } + + // things to do + checkChoiceSetParameters(); + setUpHelpItems(helpList); + } + + /** + * Constructor with all possible properties. + * + * @param title - The choice set's title + * @param listener - The choice set listener called after the user has interacted with your choice set + * @param layout - The layout of choice options (Manual/touch only) + * @param timeout - The timeout of a touch interaction (Manual/touch only) + * @param initialPrompt - A voice prompt spoken to the user when this set is displayed + * @param timeoutPrompt - A voice prompt spoken to the user when the set times out (Voice only) + * @param helpPrompt - A voice prompt spoken to the user when the user asks for "help" + * @param helpList - A table list of text and images shown to the user during a voice recognition session for this choice set (Voice only) + * @param choices - The list of choices presented to the user either as a manual/touch interaction or via the user's voice + */ + public ChoiceSet(@NonNull String title, @NonNull ChoiceSetSelectionListener listener, @Nullable ChoiceSetLayout layout, @Nullable Integer timeout, @Nullable List<TTSChunk> initialPrompt, @Nullable List<TTSChunk> timeoutPrompt, @Nullable List<TTSChunk> helpPrompt, @Nullable List<VrHelpItem> helpList, @NonNull List<ChoiceCell> choices) { + + setTitle(title); + setChoiceSetSelectionListener(listener); + setInitialPrompt(initialPrompt); + setTimeoutPrompt(timeoutPrompt); + setHelpPrompt(helpPrompt); + setChoices(choices); + setTimeout(timeout); + setLayout(layout); + + // things to do + checkChoiceSetParameters(); + setUpHelpItems(helpList); + } + + /** + * Maps to PerformInteraction.initialText. The title of the choice set, and/or the initial text on a keyboard prompt. + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title - Maps to PerformInteraction.initialText. The title of the choice set, and/or the initial text on a keyboard prompt. + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * Maps to PerformInteraction.initialPrompt. The initial prompt spoken to the user at the start of an interaction. + * @return The list of TTSChunks + */ + public List<TTSChunk> getInitialPrompt() { + return initialPrompt; + } + + /** + * @param initialPrompt - Maps to PerformInteraction.initialPrompt. The initial prompt spoken to the user at the start of an interaction. + */ + public void setInitialPrompt(List<TTSChunk> initialPrompt) { + this.initialPrompt = initialPrompt; + } + + /** + * Maps to PerformInteraction.timeoutPrompt. This text is spoken when a VR interaction times out. + * If this set is presented in a manual (non-voice) only interaction, this will be ignored. + * @return - The list of TTS Chunks + */ + public List<TTSChunk> getTimeoutPrompt() { + return timeoutPrompt; + } + + /** + * @param timeoutPrompt - Maps to PerformInteraction.timeoutPrompt. This text is spoken when a + * VR interaction times out. If this set is presented in a manual (non-voice) only interaction, this will be ignored. + */ + public void setTimeoutPrompt(List<TTSChunk> timeoutPrompt) { + this.timeoutPrompt = timeoutPrompt; + } + + /** + * Maps to PerformInteraction.helpPrompt. This is the spoken string when a user speaks "help" when the interaction is occurring. + * @return The List of TTS Chunks + */ + public List<TTSChunk> getHelpPrompt() { + return helpPrompt; + } + + /** + * @param helpPrompt - Maps to PerformInteraction.helpPrompt. This is the spoken string when a user + * speaks "help" when the interaction is occurring. + */ + public void setHelpPrompt(List<TTSChunk> helpPrompt) { + this.helpPrompt = helpPrompt; + } + + /** + * Maps to PerformInteraction.vrHelp. This is a list of help text presented to the user when + * they are in a voice recognition interaction from your choice set of options. If this set is + * presented in a touch only interaction, this will be ignored. + * + * Note: That while VRHelpItem's position will be automatically set based on position in the + * array, the image will need to uploaded by you before use using the FileManager. + * + * @return The List of VR Help Items + */ + public List<VrHelpItem> getVrHelpList() { + return vrHelpList; + } + + /** + * @param vrHelpList - Maps to PerformInteraction.vrHelp. This is a list of help text presented to the user when + * they are in a voice recognition interaction from your choice set of options. If this set is + * presented in a touch only interaction, this will be ignored. + * + * Note: That while SDLVRHelpItem's position will be automatically set based on position in the + * array, the image will need to uploaded by you before use using the FileManager. + */ + public void setVrHelpList(List<VrHelpItem> vrHelpList) { + + if (vrHelpList != null) { + for (int i = 0; i < vrHelpList.size(); i++) { + vrHelpList.get(i).setPosition(i+1); + } + } + + this.vrHelpList = vrHelpList; + } + + /** + * Maps to PerformInteraction.interactionLayout. Whether the presented choices are arranged as + * a set of tiles or a list. + * @return The ChoiceSetLayout + */ + public ChoiceSetLayout getLayout() { + return layout; + } + + /** + * @param layout - Maps to PerformInteraction.interactionLayout. Whether the presented choices + * are arranged as a set of tiles or a list. + */ + public void setLayout(ChoiceSetLayout layout) { + if (layout == null){ + this.layout = defaultLayout; + } else { + this.layout = layout; + } + } + + /** + * Maps to PerformInteraction.timeout. This applies only to a manual selection (not a voice + * selection, which has its timeout handled by the system). Defaults to `defaultTimeout`. + * @return The Timeout + */ + public Integer getTimeout() { + return timeout; + } + + /** + * @param timeout - Maps to PerformInteraction.timeout. This applies only to a manual selection + * (not a voice selection, which has its timeout handled by the system). Defaults to `defaultTimeout`. + */ + public void setTimeout(Integer timeout) { + if (timeout == null) { + this.timeout = defaultTimeout; + } else { + this.timeout = timeout; + } + } + + /** + * The choices to be displayed to the user within this choice set. These choices could match + * those already preloaded + * + * This is limited to 100 items. If you attempt to set more than 100 items, the set will not + * have any items (this array will be empty). + * @return The List of ChoiceCells + */ + public List<ChoiceCell> getChoices() { + return choices; + } + + /** + * @param choices - The choices to be displayed to the user within this choice set. These choices could match + * those already preloaded + * + * This is limited to 100 items. If you attempt to set more than 100 items, the set will not + * have any items (this array will be empty). + */ + public void setChoices(List<ChoiceCell> choices) { + this.choices = choices; + } + + /** + * The listener of this choice set, called when the user interacts with it. + * @return The listener + */ + public ChoiceSetSelectionListener getChoiceSetSelectionListener() { + return choiceSetSelectionListener; + } + + /** + * @param choiceSetSelectionListener The listener of this choice set, called when the user interacts with it. + */ + public void setChoiceSetSelectionListener(ChoiceSetSelectionListener choiceSetSelectionListener) { + this.choiceSetSelectionListener = choiceSetSelectionListener; + } + + // HELPERS + + private void checkChoiceSetParameters(){ + if (DebugTool.isDebugEnabled()) { + if (getTitle() != null) { + if (getTitle().length() == 0 || getTitle().length() > 500) { + DebugTool.logWarning("Attempted to create a choice set with a title of " + getTitle().length() + " length. Only 500 characters are supported."); + } + } + if (getTimeout() != null) { + if (getTimeout() < 5 || getTimeout() > 100) { + DebugTool.logWarning("Attempted to create a choice set with a " + getTimeout() + " second timeout; Only 5 - 100 seconds is valid"); + } + } + if (getChoices() != null) { + if (getChoices().size() == 0 || getChoices().size() > 100) { + DebugTool.logWarning("Attempted to create a choice set with "+getChoices().size()+" choices; Only 1 - 100 choices are valid"); + } + } + } + } + + private void setUpHelpItems(List<VrHelpItem> helpItems){ + // set help item positioning + if (helpItems != null) { + for (int i = 0; i < helpItems.size(); i++) { + helpItems.get(i).setPosition(i+1); + } + setVrHelpList(helpItems); + } + } + +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayout.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayout.java new file mode 100644 index 000000000..312accd75 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetLayout.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +public enum ChoiceSetLayout { + CHOICE_SET_LAYOUT_LIST, + CHOICE_SET_LAYOUT_TILES; + + public static ChoiceSetLayout valueForString(String value) { + try { + return valueOf(value); + } catch (Exception e) { + return null; + } + } +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetSelectionListener.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetSelectionListener.java new file mode 100644 index 000000000..5f477b58a --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetSelectionListener.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import com.smartdevicelink.proxy.rpc.enums.TriggerSource; + +public interface ChoiceSetSelectionListener { + void onChoiceSelected(ChoiceCell choiceCell, TriggerSource triggerSource, int rowIndex); + void onError(String error); +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardAutocompleteCompletionListener.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardAutocompleteCompletionListener.java new file mode 100644 index 000000000..a921766db --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardAutocompleteCompletionListener.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +public interface KeyboardAutocompleteCompletionListener { + + /** + * This listener is called when you wish to update your autocomplete text in response to the user's input + * @param updatedAutoCompleteText - The new autocomplete text to use + */ + void onUpdatedAutoCompleteText(String updatedAutoCompleteText); +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardCharacterSetCompletionListener.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardCharacterSetCompletionListener.java new file mode 100644 index 000000000..7221bf7d1 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardCharacterSetCompletionListener.java @@ -0,0 +1,12 @@ +package com.smartdevicelink.managers.screen.choiceset; + +import java.util.List; + +public interface KeyboardCharacterSetCompletionListener { + + /** + * This listener is called when you wish to update your keyboard's limitedCharacterSet in response to the user's input + * @param updatedCharacterSet - The new set of characters to use + */ + void onUpdatedCharacterSet(List<String> updatedCharacterSet); +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardListener.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardListener.java new file mode 100644 index 000000000..a92fafa75 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/KeyboardListener.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import com.smartdevicelink.proxy.rpc.enums.KeyboardEvent; + +public interface KeyboardListener { + + /** + * The keyboard session completed with some input. + * + * This will be sent upon ENTRY_SUBMITTED or ENTRY_VOICE. If the event is ENTRY_VOICE, the user + * requested to start a voice session in order to submit input to this keyboard. This MUST be + * handled by you. Start an Audio Pass Thru session if supported. + * + * @param inputText - The submitted input text on the keyboard + * @param event - ENTRY_SUBMITTED if the user pressed the submit button on the keyboard, ENTRY_VOICE + * if the user requested that a voice session begin + */ + void onUserDidSubmitInput(String inputText, KeyboardEvent event); + + /** + * The keyboard session aborted. + * + * This will be sent if the keyboard event ENTRY_CANCELLED or ENTRY_ABORTED is sent + * + * @param event - ENTRY_CANCELLED if the user cancelled the keyboard input, or ENTRY_ABORTED if + * the system aborted the input due to a higher priority event + */ + void onKeyboardDidAbortWithReason(KeyboardEvent event); + + /** + * Implement this in order to provide a custom keyboard configuration to just this keyboard. To + * apply default settings to all keyboards, see SDLScreenManager.keyboardConfiguration + * + * @param currentInputText - The user's full current input text + * @param keyboardAutocompleteCompletionListener - A listener to update the autoCompleteText + */ + void updateAutocompleteWithInput(String currentInputText, KeyboardAutocompleteCompletionListener keyboardAutocompleteCompletionListener); + + /** + * Implement this if you wish to update the limitedCharacterSet as the user updates their input. + * This is called upon a KEYPRESS event. + * + * @param currentInputText - The user's full current input text + * @param keyboardCharacterSetCompletionListener - A listener to update the limitedCharacterSet + */ + void updateCharacterSetWithInput(String currentInputText, KeyboardCharacterSetCompletionListener keyboardCharacterSetCompletionListener); + + /** + * Implement this to be notified of all events occurring on the keyboard + * + * @param event - The event that occurred + * @param currentInputText - The user's full current input text + */ + void onKeyboardDidSendEvent(KeyboardEvent event, String currentInputText); +}
\ No newline at end of file diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java new file mode 100644 index 000000000..2cb3ad2f3 --- /dev/null +++ b/javaSE/src/main/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManager.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.screen.choiceset; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.proxy.interfaces.ISdl; + +/** + * <strong>ChoiceSetManager</strong> <br> + * ChoiceSetManager gives the developer the ability to control how soft choice sets are displayed on the head unit.<br> + * Note: This class must be accessed through the SdlManager->ScreenManager. Do not instantiate it by itself.<br> + */ +class ChoiceSetManager extends BaseChoiceSetManager { + + /** + * Creates a new instance of the ChoiceSetManager + * + * @param internalInterface + */ + ChoiceSetManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager) { + super(internalInterface, fileManager); + } +} |