diff options
author | NicoleYarroch <nicole@livio.io> | 2019-08-07 13:23:25 -0400 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2019-08-07 13:23:25 -0400 |
commit | 2a0ba5ef02b33fc757f62a3daaeed0f34123a0da (patch) | |
tree | f2e655545a140a7c8a65475f14e342632b1154ce | |
parent | 1e9e5fe5faa5ca187fde8c2b2bd8c7496eb5bb61 (diff) | |
parent | 5ea3f89124f070f8bf9a97eeb70854ee140f23f5 (diff) | |
download | sdl_android-2a0ba5ef02b33fc757f62a3daaeed0f34123a0da.tar.gz |
Merge branch 'develop' into feature/issue_840_cancel_interaction_RPC
# Conflicts:
# android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java
# android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
# base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
29 files changed, 9308 insertions, 8550 deletions
diff --git a/.travis.yml b/.travis.yml index 96bbd4a27..625caaa52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: android jdk: oraclejdk8 +dist: trusty sudo: false android: components: @@ -8,7 +9,7 @@ android: - tools - platform-tools - ndk-bundle - + # The BuildTools version used by your project - build-tools-28.0.3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cabd706d..40d356106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,5 @@ -# 4.9.0 Release Notes +# 4.9.1 Release Notes -## Feature +### Hotfix -- [[SDL 0157] Mobile Choice Set Manager](https://github.com/smartdevicelink/sdl_java_suite/issues/764) -- [[SDL 0155] Mobile Menu Manager](https://github.com/smartdevicelink/sdl_java_suite/issues/730) -- [[SDL 0210]-Mobile Manager Dynamic Menu Cell Updating ](https://github.com/smartdevicelink/sdl_java_suite/issues/961) -- [[SDL 0232] Added Pushing Buffer Support to AudioStreamManager](https://github.com/smartdevicelink/sdl_java_suite/issues/1075) -- [Library will dynamically check if head unit requires VR synonyms for Choice items](https://github.com/smartdevicelink/sdl_java_suite/issues/941) -- [VideoStreamingManager now fully supports multi-touch events](https://github.com/smartdevicelink/sdl_java_suite/issues/972) - - - -## Bug Fixes - -- [Symlinks broken on Windows](https://github.com/smartdevicelink/sdl_java_suite/issues/1062) - Windows user must run a gradle task (`buildWindowSymLinks`) in order to create the Windows version of symlinks. -- [Audio over AOA Issues](https://github.com/smartdevicelink/sdl_java_suite/issues/1056) - Media apps will now wait until an audio output device is ready before connecting over a transport. This can be overwritten by the developer. -- [Fixed LeftRearInflatableBelted using the wrong key value in BeltStatus Class](https://github.com/smartdevicelink/sdl_java_suite/issues/1078) -- [New Router Service and old USB Transport compatibility issues](https://github.com/smartdevicelink/sdl_java_suite/issues/1064) - Fixed an issue that caused apps not close when a legacy AOA app was chosen by the user. -- [Fixed an issue with `sendSequentialRPCs` where it didn't call `onResponse` and stoped on first `onError`](https://github.com/smartdevicelink/sdl_java_suite/issues/1061) - -## Misc -- [Updated library to use the newest BSON library](https://github.com/smartdevicelink/sdl_java_suite/pull/1072) -- [Update gradle plugin](https://github.com/smartdevicelink/sdl_java_suite/pull/1077) +- [Fix ChoiceSetManager issue with HUs that require VR for choices](https://github.com/smartdevicelink/sdl_java_suite/issues/1137)
\ No newline at end of file @@ -1 +1 @@ -4.9.0
\ No newline at end of file +4.9.1
\ No newline at end of file diff --git a/android/sdl_android/src/androidTest/assets/json/Show.json b/android/sdl_android/src/androidTest/assets/json/Show.json index 97ef1f20f..db189b34a 100644 --- a/android/sdl_android/src/androidTest/assets/json/Show.json +++ b/android/sdl_android/src/androidTest/assets/json/Show.json @@ -17,6 +17,7 @@ "mainField2":"Main Field 2", "mainField3":"Main Field 3", "mainField4":"Main Field 4", + "templateTitle":"Template Title", "statusBar":"Status", "mediaClock":"Media Clock", "alignment":"LEFT_ALIGNED", diff --git a/android/sdl_android/src/androidTest/assets/json/ShowAppMenu.json b/android/sdl_android/src/androidTest/assets/json/ShowAppMenu.json new file mode 100644 index 000000000..8870423de --- /dev/null +++ b/android/sdl_android/src/androidTest/assets/json/ShowAppMenu.json @@ -0,0 +1,13 @@ +{ + "request":{ + "name":"ShowAppMenu", + "correlationID":187, + "parameters":{ + "menuID":100 + } + }, + "response":{ + "name":"ShowAppMenuResponse", + "correlationID":188 + } +}
\ No newline at end of file diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java index 5d0635e6c..1f0d57e0a 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java @@ -45,6 +45,7 @@ public class ScreenManagerTests extends AndroidTestCase2 { assertNull(screenManager.getTextField2()); assertNull(screenManager.getTextField3()); assertNull(screenManager.getTextField4()); + assertNull(screenManager.getTemplateTitle()); assertNull(screenManager.getMediaTrackTextField()); assertNull(screenManager.getPrimaryGraphic()); assertNull(screenManager.getSecondaryGraphic()); @@ -68,10 +69,12 @@ public class ScreenManagerTests extends AndroidTestCase2 { screenManager.setTextField2("Wednesday"); screenManager.setTextField3("My"); screenManager.setTextField4("Dudes"); + screenManager.setTemplateTitle("title"); assertEquals(screenManager.getTextField1(), "It is"); assertEquals(screenManager.getTextField2(), "Wednesday"); assertEquals(screenManager.getTextField3(), "My"); assertEquals(screenManager.getTextField4(), "Dudes"); + assertEquals(screenManager.getTemplateTitle(), "title"); } public void testMediaTrackTextFields() { diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java index d063f52e3..cca75223e 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java @@ -96,6 +96,7 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 { assertNull(textAndGraphicManager.getTextField2()); assertNull(textAndGraphicManager.getTextField3()); assertNull(textAndGraphicManager.getTextField4()); + assertNull(textAndGraphicManager.getTemplateTitle()); assertNull(textAndGraphicManager.getMediaTrackTextField()); assertNull(textAndGraphicManager.getPrimaryGraphic()); assertNull(textAndGraphicManager.getSecondaryGraphic()); @@ -484,6 +485,13 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 { assertEquals(textAndGraphicManager.getMediaTrackTextField(), songTitle); } + public void testTemplateTitle() { + + String title = "template title"; + textAndGraphicManager.setTemplateTitle(title); + assertEquals(textAndGraphicManager.getTemplateTitle(), title); + } + public void testAlignment() { textAndGraphicManager.setTextAlignment(TextAlignment.LEFT_ALIGNED); @@ -534,6 +542,7 @@ public class TextAndGraphicManagerTests extends AndroidTestCase2 { assertNull(textAndGraphicManager.getTextField2Type()); assertNull(textAndGraphicManager.getTextField3Type()); assertNull(textAndGraphicManager.getTextField4Type()); + assertNull(textAndGraphicManager.getTemplateTitle()); assertNotNull(textAndGraphicManager.getBlankArtwork()); assertNull(textAndGraphicManager.currentScreenData); assertNull(textAndGraphicManager.inProgressUpdate); diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java index d06d96bdc..6dfea3775 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java @@ -53,6 +53,7 @@ import com.smartdevicelink.proxy.rpc.enums.SystemContext; import com.smartdevicelink.proxy.rpc.enums.TriggerSource; import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -445,6 +446,30 @@ public class MenuManagerTests extends AndroidTestCase2 { assertEquals(menuManager.menuCells.size(), 0); } + public void testOpeningMainMenu(){ + // call open Menu + MenuManager mockMenuManager = mock(MenuManager.class); + mockMenuManager.openMenu(); + verify(mockMenuManager, Mockito.times(1)).openMenu(); + } + + public void testOpeningSubMenuNullCells(){ + // call open Menu + MenuManager mockMenuManager = mock(MenuManager.class); + MenuCell cell = mock(MenuCell.class); + mockMenuManager.oldMenuCells = null; + assertFalse(mockMenuManager.openSubMenu(cell)); + } + + public void testOpeningSubMenu(){ + // call open Menu + List<MenuCell> testCells = createTestCells(); + menuManager.oldMenuCells = testCells; + menuManager.sdlMsgVersion = new SdlMsgVersion(6,0); + // has to get success response to be true + assertTrue(menuManager.openSubMenu(testCells.get(3))); + } + public void testSetMenuConfiguration(){ menuManager.currentHMILevel = HMILevel.HMI_FULL; menuManager.currentSystemContext = SystemContext.SYSCTXT_MAIN; @@ -453,6 +478,7 @@ public class MenuManagerTests extends AndroidTestCase2 { MenuConfiguration menuConfigurationTest = new MenuConfiguration(MenuLayout.LIST, MenuLayout.LIST); menuManager.setMenuConfiguration(menuConfigurationTest); assertEquals(menuManager.menuConfiguration, menuConfigurationTest); + } // HELPERS @@ -489,7 +515,8 @@ public class MenuManagerTests extends AndroidTestCase2 { MenuCell subCell1 = new MenuCell("SubCell 1",null, null, menuSelectionListenerSub1); MenuCell subCell2 = new MenuCell("SubCell 2",null, null, menuSelectionListenerSub2); - mainCell4 = new MenuCell("Test Cell 4", MenuLayout.LIST, livio, Arrays.asList(subCell1,subCell2)); // sub menu parent cell + mainCell4 = new MenuCell("Test Cell 4", null, livio, Arrays.asList(subCell1,subCell2)); // sub menu parent cell + mainCell4.setCellId(4); return Arrays.asList(mainCell1, mainCell2, mainCell3, mainCell4); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TextFieldNameTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TextFieldNameTests.java index 4703b6ee0..33baa6835 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TextFieldNameTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/TextFieldNameTests.java @@ -11,7 +11,7 @@ import java.util.List; /** * This is a unit test class for the SmartDeviceLink library project class : - * {@link com.smartdevicelink.rpc.enums.TextFieldName} + * {@link com.smartdevicelink.proxy.rpc.enums.TextFieldName} */ public class TextFieldNameTests extends TestCase { @@ -75,6 +75,8 @@ public class TextFieldNameTests extends TestCase { TextFieldName enumAddLines = TextFieldName.valueForString(example); example = "phoneNumber"; TextFieldName enumPhone = TextFieldName.valueForString(example); + example = "templateTitle"; + TextFieldName templateTitle = TextFieldName.valueForString(example); assertNotNull("mainField1 returned null", enumMainField1); assertNotNull("mainField2 returned null", enumMainField2); @@ -100,7 +102,9 @@ public class TextFieldNameTests extends TestCase { assertNotNull("secondaryText returned null", enumSecondaryText); assertNotNull("tertiaryText returned null", enumTertiaryText); assertNotNull("menuTitle returned null", enumMenuTitle); - + assertNotNull("templateTitle returned null", templateTitle); + + assertNotNull(Test.NOT_NULL, enumLocName); assertNotNull(Test.NOT_NULL, enumLocDesc); assertNotNull(Test.NOT_NULL, enumAddLines); @@ -165,12 +169,12 @@ public class TextFieldNameTests extends TestCase { enumTestList.add(TextFieldName.menuName); enumTestList.add(TextFieldName.secondaryText); enumTestList.add(TextFieldName.tertiaryText); - enumTestList.add(TextFieldName.menuTitle); - + enumTestList.add(TextFieldName.menuTitle); enumTestList.add(TextFieldName.locationName); enumTestList.add(TextFieldName.locationDescription); enumTestList.add(TextFieldName.addressLines); - enumTestList.add(TextFieldName.phoneNumber); + enumTestList.add(TextFieldName.phoneNumber); + enumTestList.add(TextFieldName.templateTitle); 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/test/rpc/requests/ShowAppMenuTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowAppMenuTests.java new file mode 100644 index 000000000..07ff2fbfc --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowAppMenuTests.java @@ -0,0 +1,133 @@ +/* + * 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. + * + * Created by brettywhite on 7/16/19 2:27 PM + * + */ + +package com.smartdevicelink.test.rpc.requests; + +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.rpc.ShowAppMenu; +import com.smartdevicelink.test.BaseRpcTests; +import com.smartdevicelink.test.JsonUtils; +import com.smartdevicelink.test.Test; +import com.smartdevicelink.test.json.rpc.JsonFileReader; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Hashtable; + +/** + * This is a unit test class for the SmartDeviceLink library project class : + * {@link com.smartdevicelink.proxy.rpc.ShowAppMenu} + */ +public class ShowAppMenuTests extends BaseRpcTests { + + @Override + protected RPCMessage createMessage() { + ShowAppMenu msg = new ShowAppMenu(); + msg.setMenuID(Test.GENERAL_INTEGER); + return msg; + } + + @Override + protected String getMessageType() { + return RPCMessage.KEY_REQUEST; + } + + @Override + protected String getCommandType() { + return FunctionID.SHOW_APP_MENU.toString(); + } + + @Override + protected JSONObject getExpectedParameters(int sdlVersion) { + JSONObject result = new JSONObject(); + + try { + result.put(ShowAppMenu.KEY_MENU_ID, Test.GENERAL_INTEGER); + } catch (JSONException e) { + fail(Test.JSON_FAIL); + } + + return result; + } + + /** + * Tests the expected values of the RPC message. + */ + public void testRpcValues () { + // Test Values + Integer copy = ( (ShowAppMenu) msg ).getMenuID(); + + // Valid Tests + assertEquals(Test.MATCH, Test.GENERAL_INTEGER, copy); + + // Invalid/Null Tests + ShowAppMenu msg = new ShowAppMenu(); + assertNotNull(Test.NOT_NULL, msg); + testNullBase(msg); + + assertNull(Test.MATCH, msg.getMenuID()); + } + + /** + * Tests a valid JSON construction of this RPC message. + */ + public void testJsonConstructor () { + JSONObject commandJson = JsonFileReader.readId(this.mContext, getCommandType(), getMessageType()); + assertNotNull(Test.NOT_NULL, commandJson); + + try { + Hashtable<String, Object> hash = JsonRPCMarshaller.deserializeJSONObject(commandJson); + ShowAppMenu cmd = new ShowAppMenu(hash); + + JSONObject body = JsonUtils.readJsonObjectFromJsonObject(commandJson, getMessageType()); + assertNotNull(Test.NOT_NULL, body); + + // Test everything in the json body. + assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(body, RPCMessage.KEY_FUNCTION_NAME), cmd.getFunctionName()); + assertEquals(Test.MATCH, JsonUtils.readIntegerFromJsonObject(body, RPCMessage.KEY_CORRELATION_ID), cmd.getCorrelationID()); + + JSONObject parameters = JsonUtils.readJsonObjectFromJsonObject(body, RPCMessage.KEY_PARAMETERS); + + Integer serviceID = JsonUtils.readIntegerFromJsonObject(parameters, ShowAppMenu.KEY_MENU_ID); + assertEquals(Test.MATCH, Test.GENERAL_INTEGER, serviceID); + } catch (JSONException e) { + e.printStackTrace(); + } + } + +}
\ No newline at end of file diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowTests.java index 91f4c52d7..4f89763aa 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ShowTests.java @@ -27,17 +27,18 @@ import java.util.List; * {@link com.smartdevicelink.proxy.rpc.Show} */ public class ShowTests extends BaseRpcTests { - + @Override protected RPCMessage createMessage() { Show msg = new Show(); - + msg.setMainField1(Test.GENERAL_STRING); msg.setMainField2(Test.GENERAL_STRING); msg.setMainField3(Test.GENERAL_STRING); msg.setMainField4(Test.GENERAL_STRING); msg.setStatusBar(Test.GENERAL_STRING); msg.setMediaTrack(Test.GENERAL_STRING); + msg.setTemplateTitle(Test.GENERAL_STRING); msg.setAlignment(Test.GENERAL_TEXTALIGNMENT); msg.setGraphic(Test.GENERAL_IMAGE); msg.setSecondaryGraphic(Test.GENERAL_IMAGE); @@ -62,13 +63,14 @@ public class ShowTests extends BaseRpcTests { protected JSONObject getExpectedParameters(int sdlVersion) { JSONObject result = new JSONObject(); - try { + try { result.put(Show.KEY_MAIN_FIELD_1, Test.GENERAL_STRING); result.put(Show.KEY_MAIN_FIELD_2, Test.GENERAL_STRING); result.put(Show.KEY_MAIN_FIELD_3, Test.GENERAL_STRING); result.put(Show.KEY_MAIN_FIELD_4, Test.GENERAL_STRING); result.put(Show.KEY_STATUS_BAR, Test.GENERAL_STRING); result.put(Show.KEY_MEDIA_TRACK, Test.GENERAL_STRING); + result.put(Show.KEY_TEMPLATE_TITLE, Test.GENERAL_STRING); result.put(Show.KEY_GRAPHIC, Test.JSON_IMAGE); result.put(Show.KEY_SECONDARY_GRAPHIC, Test.JSON_IMAGE); result.put(Show.KEY_ALIGNMENT, Test.GENERAL_TEXTALIGNMENT); @@ -81,10 +83,11 @@ public class ShowTests extends BaseRpcTests { return result; } - + public void testSoftButtons () { // TestValues String testTrack = ( (Show) msg ).getMediaTrack(); + String templateTitle = ( (Show) msg ).getTemplateTitle(); Image testGraphic2 = ( (Show) msg ).getSecondaryGraphic(); Image testGraphic1 = ( (Show) msg ).getGraphic(); String testStatusBar = ( (Show) msg ).getStatusBar(); @@ -96,9 +99,10 @@ public class ShowTests extends BaseRpcTests { List<SoftButton> testSoftButtons = ( (Show) msg ).getSoftButtons(); List<String> testCustomPresets = ( (Show) msg ).getCustomPresets(); MetadataTags testMetadata = ( (Show) msg ).getMetadataTags(); - + // Valid Tests assertEquals(Test.MATCH, Test.GENERAL_STRING, testTrack); + assertEquals(Test.MATCH, Test.GENERAL_STRING, templateTitle); assertEquals(Test.MATCH, Test.GENERAL_TEXTALIGNMENT, testAlignment); assertEquals(Test.MATCH, Test.GENERAL_STRING, testStatusBar); assertEquals(Test.MATCH, Test.GENERAL_STRING, testText1); @@ -110,7 +114,7 @@ public class ShowTests extends BaseRpcTests { assertTrue(Test.TRUE, Validator.validateSoftButtons(Test.GENERAL_SOFTBUTTON_LIST, testSoftButtons)); assertTrue(Test.TRUE, Validator.validateImage(Test.GENERAL_IMAGE, testGraphic2)); assertTrue(Test.TRUE, Validator.validateImage(Test.GENERAL_IMAGE, testGraphic1)); - + // Invalid/Null Tests Show msg = new Show(); assertNotNull(Test.NOT_NULL, msg); @@ -126,6 +130,7 @@ public class ShowTests extends BaseRpcTests { assertNull(Test.NULL, msg.getSecondaryGraphic()); assertNull(Test.NULL, msg.getCustomPresets()); assertNull(Test.NULL, msg.getMediaTrack()); + assertNull(Test.NULL, msg.getTemplateTitle()); assertNull(Test.NULL, msg.getSoftButtons()); assertNull(Test.NULL, msg.getMetadataTags()); } @@ -166,6 +171,7 @@ public class ShowTests extends BaseRpcTests { assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(parameters, Show.KEY_STATUS_BAR), cmd.getStatusBar()); assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(parameters, Show.KEY_ALIGNMENT), cmd.getAlignment().toString()); assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(parameters, Show.KEY_MEDIA_TRACK), cmd.getMediaTrack()); + assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(parameters, Show.KEY_TEMPLATE_TITLE), cmd.getTemplateTitle()); assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(parameters, Show.KEY_METADATA_TAGS), cmd.getMetadataTags()); JSONObject secondaryGraphic = JsonUtils.readJsonObjectFromJsonObject(parameters, Show.KEY_SECONDARY_GRAPHIC); diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ShowAppMenuResponseTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ShowAppMenuResponseTests.java new file mode 100644 index 000000000..397bf43cc --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ShowAppMenuResponseTests.java @@ -0,0 +1,106 @@ +/* + * 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. + * + * Created by brettywhite on 7/16/19 2:28 PM + * + */ + +package com.smartdevicelink.test.rpc.responses; + +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.RPCMessage; +import com.smartdevicelink.proxy.rpc.ShowAppMenuResponse; +import com.smartdevicelink.test.BaseRpcTests; +import com.smartdevicelink.test.JsonUtils; +import com.smartdevicelink.test.Test; +import com.smartdevicelink.test.json.rpc.JsonFileReader; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Hashtable; + +public class ShowAppMenuResponseTests extends BaseRpcTests { + + @Override + protected RPCMessage createMessage(){ + return new ShowAppMenuResponse(); + } + + @Override + protected String getMessageType(){ + return RPCMessage.KEY_RESPONSE; + } + + @Override + protected String getCommandType(){ + return FunctionID.SHOW_APP_MENU.toString(); + } + + @Override + protected JSONObject getExpectedParameters(int sdlVersion){ + return new JSONObject(); + } + + /** + * Tests the expected values of the RPC message. + */ + public void testRpcValues () { + // Invalid/Null Tests + ShowAppMenuResponse msg = new ShowAppMenuResponse(); + assertNotNull(Test.NOT_NULL, msg); + testNullBase(msg); + } + + /** + * Tests a valid JSON construction of this RPC message. + */ + public void testJsonConstructor () { + JSONObject commandJson = JsonFileReader.readId(this.mContext, getCommandType(), getMessageType()); + assertNotNull(Test.NOT_NULL, commandJson); + + try { + Hashtable<String, Object> hash = JsonRPCMarshaller.deserializeJSONObject(commandJson); + ShowAppMenuResponse cmd = new ShowAppMenuResponse(hash); + + JSONObject body = JsonUtils.readJsonObjectFromJsonObject(commandJson, getMessageType()); + assertNotNull(Test.NOT_NULL, body); + + // Test everything in the json body. + assertEquals(Test.MATCH, JsonUtils.readStringFromJsonObject(body, RPCMessage.KEY_FUNCTION_NAME), cmd.getFunctionName()); + assertEquals(Test.MATCH, JsonUtils.readIntegerFromJsonObject(body, RPCMessage.KEY_CORRELATION_ID), cmd.getCorrelationID()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java index 50440c35b..c1f7ec124 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java @@ -104,6 +104,7 @@ import com.smartdevicelink.proxy.rpc.SetDisplayLayoutResponse; import com.smartdevicelink.proxy.rpc.SetGlobalPropertiesResponse; import com.smartdevicelink.proxy.rpc.SetInteriorVehicleDataResponse; import com.smartdevicelink.proxy.rpc.SetMediaClockTimerResponse; +import com.smartdevicelink.proxy.rpc.ShowAppMenuResponse; import com.smartdevicelink.proxy.rpc.ShowConstantTbtResponse; import com.smartdevicelink.proxy.rpc.ShowResponse; import com.smartdevicelink.proxy.rpc.SliderResponse; @@ -652,6 +653,11 @@ public class ProxyBridge implements IProxyListener{ } @Override + public void onShowAppMenuResponse(ShowAppMenuResponse response) { + onRPCReceived(response); + } + + @Override public void onUnpublishAppServiceResponse(UnpublishAppServiceResponse response) { onRPCReceived(response); } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java index 43e40be6c..d97bfbffb 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java @@ -32,8 +32,10 @@ package com.smartdevicelink.managers.lockscreen; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Bitmap; import android.os.Build; import android.util.Log; @@ -77,6 +79,10 @@ public class LockScreenManager extends BaseSubManager { protected boolean lockScreenEnabled, deviceLogoEnabled; protected int lockScreenIcon, lockScreenColor, customView; protected Bitmap deviceLogo; + private boolean mIsLockscreenDismissible; + private boolean mLockScreenHasBeenDismissed; + private String mLockscreenWarningMsg; + private BroadcastReceiver mLockscreenDismissedReceiver; public LockScreenManager(LockScreenConfig lockScreenConfig, Context context, ISdl internalInterface){ @@ -108,6 +114,11 @@ public class LockScreenManager extends BaseSubManager { // send broadcast to close lock screen if open if (context.get() != null) { context.get().sendBroadcast(new Intent(SDLLockScreenActivity.CLOSE_LOCK_SCREEN_ACTION)); + try { + context.get().unregisterReceiver(mLockscreenDismissedReceiver); + } catch (IllegalArgumentException e) { + //do nothing + } } // remove listeners internalInterface.removeOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, hmiListener); @@ -166,6 +177,14 @@ public class LockScreenManager extends BaseSubManager { // do something with the status if (notification != null) { OnDriverDistraction ddState = (OnDriverDistraction) notification; + Boolean isDismissible = ddState.getLockscreenDismissibility(); + if (isDismissible != null) { + mIsLockscreenDismissible = isDismissible; + if (!mIsLockscreenDismissible) { + mLockScreenHasBeenDismissed = false; + } + } + mLockscreenWarningMsg = ddState.getLockscreenWarningMessage(); if (ddState.getState() == DriverDistractionState.DD_ON){ // launch lock screen @@ -226,6 +245,15 @@ public class LockScreenManager extends BaseSubManager { } else{ isApplicationForegrounded = true; } + + mLockscreenDismissedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED.equals(intent.getAction())) { + mLockScreenHasBeenDismissed = true; + } + } + }; } //// @@ -240,9 +268,16 @@ public class LockScreenManager extends BaseSubManager { * X. If the status is set to OFF, Send broadcast to close lock screen if it is open */ private void launchLockScreenActivity(){ + //If the user has dismissed the lockscreen for this run, do not show it again + if (mLockScreenHasBeenDismissed) { + return; + } // intent to open SDLLockScreenActivity // pass in icon, background color, and custom view if (lockScreenEnabled && isApplicationForegrounded && context.get() != null) { + if (mIsLockscreenDismissible) { + context.get().registerReceiver(mLockscreenDismissedReceiver, new IntentFilter(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSED)); + } LockScreenStatus status = getLockScreenStatus(); if (status == LockScreenStatus.REQUIRED) { Intent showLockScreenIntent = new Intent(context.get(), SDLLockScreenActivity.class); @@ -254,6 +289,8 @@ public class LockScreenManager extends BaseSubManager { showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_CUSTOM_VIEW_EXTRA, customView); showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_EXTRA, deviceLogoEnabled); showLockScreenIntent.putExtra(SDLLockScreenActivity.LOCKSCREEN_DEVICE_LOGO_BITMAP, deviceLogo); + showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_DISMISSIBLE, mIsLockscreenDismissible); + showLockScreenIntent.putExtra(SDLLockScreenActivity.KEY_LOCKSCREEN_WARNING_MSG, mLockscreenWarningMsg); context.get().startActivity(showLockScreenIntent); } else if (status == LockScreenStatus.OFF) { context.get().sendBroadcast(new Intent(SDLLockScreenActivity.CLOSE_LOCK_SCREEN_ACTION)); diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java index 6ae10ec73..285a5643a 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java @@ -39,9 +39,12 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.os.Bundle; +import android.view.GestureDetector; +import android.view.MotionEvent; import android.view.Window; import android.widget.ImageView; import android.widget.RelativeLayout; +import android.widget.TextView; import com.smartdevicelink.R; @@ -55,6 +58,12 @@ public class SDLLockScreenActivity extends Activity { public static final String LOCKSCREEN_CUSTOM_VIEW_EXTRA = "LOCKSCREEN_CUSTOM_VIEW_EXTRA"; public static final String LOCKSCREEN_DEVICE_LOGO_DOWNLOADED = "LOCKSCREEN_DEVICE_LOGO_DOWNLOADED"; public static final String CLOSE_LOCK_SCREEN_ACTION = "CLOSE_LOCK_SCREEN"; + public static final String KEY_LOCKSCREEN_DISMISSED = "KEY_LOCKSCREEN_DISMISSED"; + public static final String KEY_LOCKSCREEN_DISMISSIBLE = "KEY_LOCKSCREEN_DISMISSIBLE"; + public static final String KEY_LOCKSCREEN_WARNING_MSG = "KEY_LOCKSCREEN_WARNING_MSG"; + private static final int MIN_SWIPE_DISTANCE = 200; + private boolean mIsDismissible; + private GestureDetector mGestureDetector; private final BroadcastReceiver lockScreenBroadcastReceiver = new BroadcastReceiver() { @Override @@ -81,6 +90,7 @@ public class SDLLockScreenActivity extends Activity { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); + mGestureDetector = new GestureDetector(this, new SwipeUpGestureListener()); // set any parameters that came from the lock screen manager initializeActivity(getIntent()); @@ -94,6 +104,14 @@ public class SDLLockScreenActivity extends Activity { } @Override + public boolean onTouchEvent(MotionEvent event) { + if (mIsDismissible) { + return mGestureDetector.onTouchEvent(event); + } + return super.onTouchEvent(event); + } + + @Override protected void onDestroy() { unregisterReceiver(lockScreenBroadcastReceiver); super.onDestroy(); @@ -133,6 +151,11 @@ public class SDLLockScreenActivity extends Activity { if (deviceLogoEnabled && deviceIcon != null){ setDeviceLogo(deviceIcon); } + mIsDismissible = intent.getBooleanExtra(KEY_LOCKSCREEN_DISMISSIBLE, false); + String warningMsg = intent.getStringExtra(KEY_LOCKSCREEN_WARNING_MSG); + if (mIsDismissible) { + setLockscreenWarningMessage(warningMsg); + } } } } @@ -154,8 +177,26 @@ public class SDLLockScreenActivity extends Activity { } } + private void setLockscreenWarningMessage(String msg) { + TextView tv = findViewById(R.id.lockscreen_text); + if (tv != null) { + tv.setText(msg != null ? msg : getString(R.string.default_lockscreen_warning_message)); + } + } + private void setCustomView(int customView) { setContentView(customView); } + private class SwipeUpGestureListener extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onFling(MotionEvent event1, MotionEvent event2, + float velocityX, float velocityY) { + if ((event2.getY() - event1.getY()) > MIN_SWIPE_DISTANCE) { + sendBroadcast(new Intent(KEY_LOCKSCREEN_DISMISSED)); + finish(); + } + return true; + } + } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java index 61495c51d..ae8987a89 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java @@ -1,8354 +1,8370 @@ -/*
- * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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.proxy;
-
-import android.annotation.TargetApi;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.support.annotation.NonNull;
-import android.telephony.TelephonyManager;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.Surface;
-
-import com.smartdevicelink.BuildConfig;
-import com.smartdevicelink.Dispatcher.IDispatchingStrategy;
-import com.smartdevicelink.Dispatcher.ProxyMessageDispatcher;
-import com.smartdevicelink.SdlConnection.ISdlConnectionListener;
-import com.smartdevicelink.SdlConnection.SdlConnection;
-import com.smartdevicelink.SdlConnection.SdlSession;
-import com.smartdevicelink.SdlConnection.SdlSession2;
-import com.smartdevicelink.encoder.VirtualDisplayEncoder;
-import com.smartdevicelink.exception.SdlException;
-import com.smartdevicelink.exception.SdlExceptionCause;
-import com.smartdevicelink.haptic.HapticInterfaceManager;
-import com.smartdevicelink.managers.lifecycle.RpcConverter;
-import com.smartdevicelink.marshal.JsonRPCMarshaller;
-import com.smartdevicelink.protocol.ProtocolMessage;
-import com.smartdevicelink.protocol.enums.FunctionID;
-import com.smartdevicelink.protocol.enums.MessageType;
-import com.smartdevicelink.protocol.enums.SessionType;
-import com.smartdevicelink.protocol.heartbeat.HeartbeatMonitor;
-import com.smartdevicelink.proxy.LockScreenManager.OnLockScreenIconDownloadedListener;
-import com.smartdevicelink.proxy.callbacks.InternalProxyMessage;
-import com.smartdevicelink.proxy.callbacks.OnError;
-import com.smartdevicelink.proxy.callbacks.OnProxyClosed;
-import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
-import com.smartdevicelink.proxy.callbacks.OnServiceNACKed;
-import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
-import com.smartdevicelink.proxy.interfaces.IProxyListenerBase;
-import com.smartdevicelink.proxy.interfaces.IPutFileResponseListener;
-import com.smartdevicelink.proxy.interfaces.ISdl;
-import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
-import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
-import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
-import com.smartdevicelink.proxy.rpc.*;
-import com.smartdevicelink.proxy.rpc.enums.AppHMIType;
-import com.smartdevicelink.proxy.rpc.enums.AudioStreamingState;
-import com.smartdevicelink.proxy.rpc.enums.AudioType;
-import com.smartdevicelink.proxy.rpc.enums.BitsPerSample;
-import com.smartdevicelink.proxy.rpc.enums.ButtonName;
-import com.smartdevicelink.proxy.rpc.enums.DriverDistractionState;
-import com.smartdevicelink.proxy.rpc.enums.FileType;
-import com.smartdevicelink.proxy.rpc.enums.GlobalProperty;
-import com.smartdevicelink.proxy.rpc.enums.HMILevel;
-import com.smartdevicelink.proxy.rpc.enums.ImageType;
-import com.smartdevicelink.proxy.rpc.enums.InteractionMode;
-import com.smartdevicelink.proxy.rpc.enums.Language;
-import com.smartdevicelink.proxy.rpc.enums.PrerecordedSpeech;
-import com.smartdevicelink.proxy.rpc.enums.RequestType;
-import com.smartdevicelink.proxy.rpc.enums.Result;
-import com.smartdevicelink.proxy.rpc.enums.SamplingRate;
-import com.smartdevicelink.proxy.rpc.enums.SdlConnectionState;
-import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason;
-import com.smartdevicelink.proxy.rpc.enums.SdlInterfaceAvailability;
-import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
-import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
-import com.smartdevicelink.proxy.rpc.enums.TouchType;
-import com.smartdevicelink.proxy.rpc.enums.UpdateMode;
-import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener;
-import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener;
-import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener;
-import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
-import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener;
-import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
-import com.smartdevicelink.security.SdlSecurityBase;
-import com.smartdevicelink.streaming.StreamRPCPacketizer;
-import com.smartdevicelink.streaming.audio.AudioStreamingCodec;
-import com.smartdevicelink.streaming.audio.AudioStreamingParams;
-import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
-import com.smartdevicelink.streaming.video.VideoStreamingParameters;
-import com.smartdevicelink.trace.SdlTrace;
-import com.smartdevicelink.trace.TraceDeviceInfo;
-import com.smartdevicelink.trace.enums.InterfaceActivityDirection;
-import com.smartdevicelink.transport.BaseTransportConfig;
-import com.smartdevicelink.transport.MultiplexTransportConfig;
-import com.smartdevicelink.transport.SiphonServer;
-import com.smartdevicelink.transport.USBTransportConfig;
-import com.smartdevicelink.transport.enums.TransportType;
-import com.smartdevicelink.util.CorrelationIdGenerator;
-import com.smartdevicelink.util.DebugTool;
-import com.smartdevicelink.util.FileUtls;
-import com.smartdevicelink.util.Version;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.DataOutputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.ProtocolException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.ScheduledExecutorService;
-
-
-
-@SuppressWarnings({"WeakerAccess", "Convert2Diamond"})
-public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> {
- // Used for calls to Android Log class.
- public static final String TAG = "SdlProxy";
- private static final String SDL_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66";
- private static final int PROX_PROT_VER_ONE = 1;
- private static final int RESPONSE_WAIT_TIME = 2000;
-
- public static final com.smartdevicelink.util.Version MAX_SUPPORTED_RPC_VERSION = new com.smartdevicelink.util.Version("6.0.0");
-
- private SdlSession sdlSession = null;
- private proxyListenerType _proxyListener = null;
-
- protected Service _appService = null;
- private Context _appContext;
- private String sPoliciesURL = ""; //for testing only
-
- // Protected Correlation IDs
- private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529,
- UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530,
- POLICIES_CORRELATION_ID = 65535;
-
- // Sdl Synchronization Objects
- private static final Object CONNECTION_REFERENCE_LOCK = new Object(),
- INCOMING_MESSAGE_QUEUE_THREAD_LOCK = new Object(),
- OUTGOING_MESSAGE_QUEUE_THREAD_LOCK = new Object(),
- INTERNAL_MESSAGE_QUEUE_THREAD_LOCK = new Object(),
- ON_UPDATE_LISTENER_LOCK = new Object(),
- RPC_LISTENER_LOCK = new Object(),
- ON_NOTIFICATION_LISTENER_LOCK = new Object();
-
- private final Object APP_INTERFACE_REGISTERED_LOCK = new Object();
-
- private int iFileCount = 0;
-
- private boolean navServiceStartResponseReceived = false;
- private boolean navServiceStartResponse = false;
- private List<String> navServiceStartRejectedParams = null;
- private boolean pcmServiceStartResponseReceived = false;
- private boolean pcmServiceStartResponse = false;
- @SuppressWarnings("FieldCanBeLocal")
- private List<String> pcmServiceStartRejectedParams = null;
- private boolean navServiceEndResponseReceived = false;
- private boolean navServiceEndResponse = false;
- private boolean pcmServiceEndResponseReceived = false;
- private boolean pcmServiceEndResponse = false;
- private boolean rpcProtectedResponseReceived = false;
- private boolean rpcProtectedStartResponse = false;
-
- // Device Info for logging
- private TraceDeviceInfo _traceDeviceInterrogator = null;
-
- // Declare Queuing Threads
- private ProxyMessageDispatcher<ProtocolMessage> _incomingProxyMessageDispatcher;
- private ProxyMessageDispatcher<ProtocolMessage> _outgoingProxyMessageDispatcher;
- private ProxyMessageDispatcher<InternalProxyMessage> _internalProxyMessageDispatcher;
-
- // Flag indicating if callbacks should be called from UIThread
- private Boolean _callbackToUIThread = false;
- // UI Handler
- private Handler _mainUIHandler = null;
- final int HEARTBEAT_CORRELATION_ID = 65531;
-
- // SdlProxy Advanced Lifecycle Management
- protected Boolean _advancedLifecycleManagementEnabled = false;
- // Parameters passed to the constructor from the app to register an app interface
- private String _applicationName = null;
- private final long instanceDateTime = System.currentTimeMillis();
- private String sConnectionDetails = "N/A";
- private Vector<TTSChunk> _ttsName = null;
- private String _ngnMediaScreenAppName = null;
- private Boolean _isMediaApp = null;
- private Language _sdlLanguageDesired = null;
- private Language _hmiDisplayLanguageDesired = null;
- private Vector<AppHMIType> _appType = null;
- private String _appID = null;
- private TemplateColorScheme _dayColorScheme = null;
- private TemplateColorScheme _nightColorScheme = null;
- @SuppressWarnings({"FieldCanBeLocal", "unused"}) //Need to understand what this is used for
- private String _autoActivateIdDesired = null;
- private String _lastHashID = null;
- private SdlMsgVersion _sdlMsgVersionRequest = null;
- private Vector<String> _vrSynonyms = null;
- private boolean _bAppResumeEnabled = false;
- private OnSystemRequest lockScreenIconRequest = null;
- private TelephonyManager telephonyManager = null;
- private DeviceInfo deviceInfo = null;
-
- /**
- * Contains current configuration for the transport that was selected during
- * construction of this object
- */
- private BaseTransportConfig _transportConfig = null;
- // Proxy State Variables
- protected Boolean _appInterfaceRegisterd = false;
- protected Boolean _preRegisterd = false;
- @SuppressWarnings({"unused", "FieldCanBeLocal"})
- private Boolean _haveReceivedFirstNonNoneHMILevel = false;
- protected Boolean _haveReceivedFirstFocusLevel = false;
- protected Boolean _haveReceivedFirstFocusLevelFull = false;
- protected Boolean _proxyDisposed = false;
- protected SdlConnectionState _sdlConnectionState = null;
- protected SdlInterfaceAvailability _sdlIntefaceAvailablity = null;
- protected HMILevel _hmiLevel = null;
- protected OnHMIStatus lastHmiStatus;
- protected AudioStreamingState _audioStreamingState = null;
- // Variables set by RegisterAppInterfaceResponse
- protected SdlMsgVersion _sdlMsgVersion = null;
- protected String _autoActivateIdReturned = null;
- protected Language _sdlLanguage = null;
- protected Language _hmiDisplayLanguage = null;
- protected List<PrerecordedSpeech> _prerecordedSpeech = null;
- protected VehicleType _vehicleType = null;
- protected String _systemSoftwareVersion = null;
- protected List<Integer> _diagModes = null;
- protected Boolean firstTimeFull = true;
- protected String _proxyVersionInfo = null;
- protected Boolean _bResumeSuccess = false;
- protected List<Class<? extends SdlSecurityBase>> _secList = null;
- protected SystemCapabilityManager _systemCapabilityManager;
- protected Boolean _iconResumed = false;
- protected RegisterAppInterfaceResponse raiResponse = null;
-
- private final CopyOnWriteArrayList<IPutFileResponseListener> _putFileListenerList = new CopyOnWriteArrayList<IPutFileResponseListener>();
-
- protected com.smartdevicelink.util.Version protocolVersion = new com.smartdevicelink.util.Version(1,0,0);
- protected com.smartdevicelink.util.Version rpcSpecVersion;
-
- protected SparseArray<OnRPCResponseListener> rpcResponseListeners = null;
- protected SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>> rpcNotificationListeners = null;
- protected SparseArray<CopyOnWriteArrayList<OnRPCRequestListener>> rpcRequestListeners = null;
- protected SparseArray<CopyOnWriteArrayList<OnRPCListener>> rpcListeners = null;
-
- protected VideoStreamingManager manager; //Will move to SdlSession once the class becomes public
-
- protected String authToken;
-
- private Version minimumProtocolVersion;
- private Version minimumRPCVersion;
-
-
- // Interface broker
- private SdlInterfaceBroker _interfaceBroker = null;
- //We create an easily passable anonymous class of the interface so that we don't expose the internal interface to developers
- private ISdl _internalInterface = new ISdl() {
- @Override
- public void start() {
- try{
- initializeProxy();
- }catch (SdlException e){
- e.printStackTrace();
- }
- }
-
- @Override
- public void stop() {
- try{
- dispose();
- }catch (SdlException e){
- e.printStackTrace();
- }
- }
-
- @Override
- public boolean isConnected() {
- return getIsConnected();
- }
-
- @Override
- public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
- SdlProxyBase.this.addServiceListener(serviceType,sdlServiceListener);
- }
-
- @Override
- public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
- SdlProxyBase.this.removeServiceListener(serviceType,sdlServiceListener);
- }
-
- @Override
- public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) {
- if(isConnected()){
- sdlSession.setDesiredVideoParams(parameters);
- sdlSession.startService(SessionType.NAV,sdlSession.getSessionId(),encrypted);
- }
- }
-
- @Override
- public void stopVideoService() {
- if(isConnected()){
- sdlSession.endService(SessionType.NAV,sdlSession.getSessionId());
- }
- }
-
- @Override public void stopAudioService() {
- if(isConnected()){
- sdlSession.endService(SessionType.PCM,sdlSession.getSessionId());
- }
- }
-
- @Override
- public void sendRPCRequest(RPCRequest message){
- try {
- SdlProxyBase.this.sendRPCRequest(message);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void sendRPC(RPCMessage message) {
- try {
- SdlProxyBase.this.sendRPC(message);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void sendRequests(List<? extends RPCRequest> rpcs, OnMultipleRequestListener listener) {
- try {
- SdlProxyBase.this.sendRequests(rpcs, listener);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void sendSequentialRPCs(List<? extends RPCMessage> rpcs, OnMultipleRequestListener listener) {
- try{
- SdlProxyBase.this.sendSequentialRequests(rpcs,listener);
- }catch (SdlException e ){
- DebugTool.logError("Issue sending sequential RPCs ", e);
- }
- }
-
- @Override
- public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {
- SdlProxyBase.this.addOnRPCNotificationListener(notificationId,listener);
- }
-
- @Override
- public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {
- return SdlProxyBase.this.removeOnRPCNotificationListener(notificationId,listener);
- }
-
- @Override
- public void addOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) {
- SdlProxyBase.this.addOnRPCRequestListener(functionID,listener);
- }
-
- @Override
- public boolean removeOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) {
- return SdlProxyBase.this.removeOnRPCRequestListener(functionID,listener);
- }
-
- @Override
- public void addOnRPCListener(FunctionID responseId, OnRPCListener listener) {
- SdlProxyBase.this.addOnRPCListener(responseId, listener);
- }
-
- @Override
- public boolean removeOnRPCListener(FunctionID responseId, OnRPCListener listener) {
- return SdlProxyBase.this.removeOnRPCListener(responseId, listener);
- }
-
- @Override
- public Object getCapability(SystemCapabilityType systemCapabilityType){
- return SdlProxyBase.this.getCapability(systemCapabilityType);
- }
-
- @Override
- public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) {
- SdlProxyBase.this.getCapability(systemCapabilityType, scListener);
- }
-
- @Override
- public SdlMsgVersion getSdlMsgVersion(){
- try {
- return SdlProxyBase.this.getSdlMsgVersion();
- } catch (SdlException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- public com.smartdevicelink.util.Version getProtocolVersion() {
- return SdlProxyBase.this.protocolVersion;
- }
-
- @Override
- public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){
- return SdlProxyBase.this.isCapabilitySupported(systemCapabilityType);
- }
-
- @Override
- public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
- SdlProxyBase.this.removeOnSystemCapabilityListener(systemCapabilityType, listener);
- }
-
- @Override
- public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) {
- return SdlProxyBase.this.removeOnSystemCapabilityListener(systemCapabilityType, listener);
- }
-
- @Override
- public boolean isTransportForServiceAvailable(SessionType serviceType) {
- return SdlProxyBase.this.sdlSession != null
- && SdlProxyBase.this.sdlSession.isTransportForServiceAvailable(serviceType);
- }
-
- @Override
- public void startAudioService(boolean isEncrypted, AudioStreamingCodec codec,
- AudioStreamingParams params) {
- if(getIsConnected()){
- SdlProxyBase.this.startAudioStream(isEncrypted, codec, params);
- }
- }
-
- @Override
- public void startAudioService(boolean encrypted) {
- if(isConnected()){
- sdlSession.startService(SessionType.PCM,sdlSession.getSessionId(),encrypted);
- }
- }
-
- @Override
- public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){
- return SdlProxyBase.this.startVideoStream(isEncrypted, parameters);
- }
-
- @Override
- public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec,
- AudioStreamingParams params) {
- return SdlProxyBase.this.startAudioStream(isEncrypted, codec, params);
- }
- };
-
- private void notifyPutFileStreamError(Exception e, String info)
- {
- for (IPutFileResponseListener _putFileListener : _putFileListenerList) {
- _putFileListener.onPutFileStreamError(e, info);
- }
- }
-
- private void notifyPutFileStreamResponse(PutFileResponse msg)
- {
- for (IPutFileResponseListener _putFileListener : _putFileListenerList) {
- _putFileListener.onPutFileResponse(msg);
- }
- }
-
- public void addPutFileResponseListener(IPutFileResponseListener _putFileListener)
- {
- _putFileListenerList.addIfAbsent(_putFileListener);
- }
-
- public void remPutFileResponseListener(IPutFileResponseListener _putFileListener)
- {
- _putFileListenerList.remove(_putFileListener);
- }
-
- // Private Class to Interface with SdlConnection
- private class SdlInterfaceBroker implements ISdlConnectionListener {
-
- @Override
- public void onTransportDisconnected(String info) {
- // proxyOnTransportDisconnect is called to alert the proxy that a requested
- // disconnect has completed
- notifyPutFileStreamError(null, info);
-
- //if (!_advancedLifecycleManagementEnabled) {
- // If original model, notify app the proxy is closed so it will delete and reinstanciate
- Log.d(TAG, "notifying proxy of closed");
- notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT);
- //}// else If ALM, nothing is required to be done here
-
- }
-
- @Override
- public void onTransportDisconnected(String info, boolean altTransportAvailable, BaseTransportConfig transportConfig) {
- notifyPutFileStreamError(null, info);
-
- if( altTransportAvailable){
- SdlProxyBase.this._transportConfig = transportConfig;
- Log.d(TAG, "notifying RPC session ended, but potential primary transport available");
- cycleProxy(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST);
-
- }else{
- notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT);
- }
- }
-
- @Override
- public void onTransportError(String info, Exception e) {
- DebugTool.logError("Transport failure: " + info, e);
-
- notifyPutFileStreamError(e, info);
-
- if (_advancedLifecycleManagementEnabled) {
- // Cycle the proxy
- if(SdlConnection.isLegacyModeEnabled()){ //FIXME
- cycleProxy(SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED);
-
- }else{
- cycleProxy(SdlDisconnectedReason.TRANSPORT_ERROR);
- }
- } else {
- notifyProxyClosed(info, e, SdlDisconnectedReason.TRANSPORT_ERROR);
- }
- }
-
- @Override
- public void onProtocolMessageReceived(ProtocolMessage msg) {
-
- // AudioPathThrough is coming WITH BulkData but WITHOUT JSON Data
- // Policy Snapshot is coming WITH BulkData and WITH JSON Data
- if ((msg.getData() != null && msg.getData().length > 0) ||
- (msg.getBulkData() != null && msg.getBulkData().length > 0)) {
- queueIncomingMessage(msg);
- }
- }
-
- @Override
- public void onProtocolSessionStarted(SessionType sessionType,
- byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted) {
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStarted");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " ServiceType: " + sessionType.getName());
- updateBroadcastIntent(sendIntent, "COMMENT3", " Encrypted: " + isEncrypted);
- sendBroadcastIntent(sendIntent);
-
- if(sdlSession!= null){
- setProtocolVersion(sdlSession.getProtocolVersion());
- }else{
- setProtocolVersion(new com.smartdevicelink.util.Version(version,0,0));
- }
-
-
- if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1){
- Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion()));
- endService(sessionType);
- try {
- cleanProxy(SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- return;
- }
-
-
- if (sessionType.eq(SessionType.RPC)) {
-
- if (!isEncrypted)
- {
- if ( (_transportConfig.getHeartBeatTimeout() != Integer.MAX_VALUE) && (version > 2))
- {
- HeartbeatMonitor outgoingHeartbeatMonitor = new HeartbeatMonitor();
- outgoingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout());
- sdlSession.setOutgoingHeartbeatMonitor(outgoingHeartbeatMonitor);
-
- HeartbeatMonitor incomingHeartbeatMonitor = new HeartbeatMonitor();
- incomingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout());
- sdlSession.setIncomingHeartbeatMonitor(incomingHeartbeatMonitor);
- }
-
- startRPCProtocolSession();
- }
- else
- {
- RPCProtectedServiceStarted();
- }
- } else if (sessionType.eq(SessionType.NAV)) {
- NavServiceStarted();
- } else if (sessionType.eq(SessionType.PCM)) {
- AudioServiceStarted();
- } else if (sessionType.eq(SessionType.RPC)){
- cycleProxy(SdlDisconnectedReason.RPC_SESSION_ENDED);
- }
- else if (protocolVersion!= null && protocolVersion.getMajor() > 1) {
- //If version is 2 or above then don't need to specify a Session Type
- startRPCProtocolSession();
- } //else{} Handle other protocol session types here
-
- }
-
- @Override
- public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
- OnServiceNACKed message = new OnServiceNACKed(sessionType);
- queueInternalMessage(message);
-
- if (sessionType.eq(SessionType.NAV)) {
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStartedNACKed");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- NavServiceStartedNACK(rejectedParams);
- }
- else if (sessionType.eq(SessionType.PCM)) {
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStartedNACKed");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- AudioServiceStartedNACK(rejectedParams);
- }
- }
-
- @Override
- public void onProtocolSessionEnded(SessionType sessionType,
- byte sessionID, String correlationID) {
- OnServiceEnded message = new OnServiceEnded(sessionType);
- queueInternalMessage(message);
-
- if (sessionType.eq(SessionType.NAV)) {
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEnded");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " End ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- NavServiceEnded();
- }
- else if (sessionType.eq(SessionType.PCM)) {
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEnded");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " End ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- AudioServiceEnded();
- }
- }
-
- @Override
- public void onProtocolError(String info, Exception e) {
- notifyPutFileStreamError(e, info);
- passErrorToProxyListener(info, e);
- }
-
- @Override
- public void onHeartbeatTimedOut(byte sessionID) {
- final String msg = "Heartbeat timeout";
- DebugTool.logInfo(msg);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onHeartbeatTimedOut");
- updateBroadcastIntent(sendIntent, "COMMENT1", "Heartbeat timeout for SessionID: " + sessionID);
- sendBroadcastIntent(sendIntent);
-
- notifyProxyClosed(msg, new SdlException(msg, SdlExceptionCause.HEARTBEAT_PAST_DUE), SdlDisconnectedReason.HB_TIMEOUT);
-
- }
-
- @Override
- public void onProtocolSessionEndedNACKed(SessionType sessionType,
- byte sessionID, String correlationID) {
- if (sessionType.eq(SessionType.NAV)) {
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEndedNACKed");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " End NACK ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- NavServiceEndedNACK();
- }
- else if (sessionType.eq(SessionType.PCM)) {
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEndedNACKed");
- updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID);
- updateBroadcastIntent(sendIntent, "COMMENT2", " End NACK ServiceType: " + sessionType.getName());
- sendBroadcastIntent(sendIntent);
-
- AudioServiceEndedNACK();
- }
-
- }
-
- public void onProtocolServiceDataACK(SessionType sessionType, final int dataSize,
- byte sessionID) {
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onServiceDataACK(dataSize);
- }
- });
- } else {
- _proxyListener.onServiceDataACK(dataSize);
- }
- }
-
- @Override
- public void onAuthTokenReceived(String authToken, byte sessionID) {
- SdlProxyBase.this.authToken = authToken;
- }
- }
-
- protected SdlProxyBase(){}
-
- /**
- * Used by the SdlManager
- *
- * @param listener Type of listener for this proxy base.
- * @param context Application context.
- * @param appName Client application name.
- * @param shortAppName Client short application name.
- * @param isMediaApp Flag that indicates that client application if media application or not.
- * @param languageDesired Desired language.
- * @param hmiDisplayLanguageDesired Desired language for HMI.
- * @param appType Type of application.
- * @param appID Application identifier.
- * @param dayColorScheme TemplateColorScheme for the day
- * @param nightColorScheme TemplateColorScheme for the night
- * @param transportConfig Configuration of transport to be used by underlying connection.
- * @param vrSynonyms List of synonyms.
- * @param ttsName TTS name.
- * @throws SdlException
- */
- public SdlProxyBase(proxyListenerType listener, Context context, String appName,String shortAppName, Boolean isMediaApp, Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- BaseTransportConfig transportConfig, Vector<String> vrSynonyms, Vector<TTSChunk> ttsName, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme) throws SdlException {
- performBaseCommon(listener, null, true, appName, ttsName, shortAppName, vrSynonyms, isMediaApp,
- null, languageDesired, hmiDisplayLanguageDesired, appType, appID, null, dayColorScheme,nightColorScheme, false, false, null, null, transportConfig);
- _appContext = context;
- }
-
- /**
- * Constructor.
- *
- * @param listener Type of listener for this proxy base.
- * @param sdlProxyConfigurationResources Configuration resources for this proxy.
- * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not.
- * @param appName Client application name.
- * @param ttsName TTS name.
- * @param ngnMediaScreenAppName Media Screen Application name.
- * @param vrSynonyms List of synonyms.
- * @param isMediaApp Flag that indicates that client application if media application or not.
- * @param sdlMsgVersion Version of Sdl Message.
- * @param languageDesired Desired language.
- * @param hmiDisplayLanguageDesired Desired language for HMI.
- * @param appType Type of application.
- * @param appID Application identifier.
- * @param autoActivateID Auto activation identifier.
- * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not.
- * @param transportConfig Configuration of transport to be used by underlying connection.
- * @throws SdlException if there is an unrecoverable error class might throw an exception.
- */
- protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, boolean callbackToUIThread, BaseTransportConfig transportConfig)
- throws SdlException {
-
- performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp,
- sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, null, null, callbackToUIThread, null, null, null, transportConfig);
- }
-
- @SuppressWarnings("ConstantConditions")
- private void performBaseCommon(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme,
- boolean callbackToUIThread, Boolean preRegister, String sHashID, Boolean bAppResumeEnab,
- BaseTransportConfig transportConfig) throws SdlException
- {
- Log.i(TAG, "SDL_LIB_VERSION: " + BuildConfig.VERSION_NAME);
- setProtocolVersion(new Version(PROX_PROT_VER_ONE,0,0));
-
- if (preRegister != null && preRegister)
- {
- _appInterfaceRegisterd = preRegister;
- _preRegisterd = preRegister;
- }
-
- if (bAppResumeEnab != null && bAppResumeEnab)
- {
- _bAppResumeEnabled = true;
- _lastHashID = sHashID;
- }
- _interfaceBroker = new SdlInterfaceBroker();
-
- _callbackToUIThread = callbackToUIThread;
-
- if (_callbackToUIThread) {
- _mainUIHandler = new Handler(Looper.getMainLooper());
- }
-
- // Set variables for Advanced Lifecycle Management
- _advancedLifecycleManagementEnabled = enableAdvancedLifecycleManagement;
- _applicationName = appName;
- _ttsName = ttsName;
- _ngnMediaScreenAppName = ngnMediaScreenAppName;
- _isMediaApp = isMediaApp;
- _sdlMsgVersionRequest = sdlMsgVersion;
- _vrSynonyms = vrSynonyms;
- _sdlLanguageDesired = languageDesired;
- _hmiDisplayLanguageDesired = hmiDisplayLanguageDesired;
- _appType = appType;
- _appID = appID;
- _autoActivateIdDesired = autoActivateID;
- _dayColorScheme = dayColorScheme;
- _nightColorScheme = nightColorScheme;
- _transportConfig = transportConfig;
-
- // Test conditions to invalidate the proxy
- if (listener == null) {
- throw new IllegalArgumentException("IProxyListener listener must be provided to instantiate SdlProxy object.");
- }
- if (_advancedLifecycleManagementEnabled) {
- /* if (_applicationName == null ) {
- throw new IllegalArgumentException("To use SdlProxyALM, an application name, appName, must be provided");
- }
- if (_applicationName.length() < 1 || _applicationName.length() > 100) {
- throw new IllegalArgumentException("A provided application name, appName, must be between 1 and 100 characters in length.");
- }*/
- if (_isMediaApp == null) {
- throw new IllegalArgumentException("isMediaApp must not be null when using SdlProxyALM.");
- }
- }
-
- _proxyListener = listener;
-
- // Get information from sdlProxyConfigurationResources
- if (sdlProxyConfigurationResources != null) {
- telephonyManager = sdlProxyConfigurationResources.getTelephonyManager();
- }
-
- // Use the telephonyManager to get and log phone info
- if (telephonyManager != null) {
- // Following is not quite thread-safe (because m_traceLogger could test null twice),
- // so we need to fix this, but vulnerability (i.e. two instances of listener) is
- // likely harmless.
- if (_traceDeviceInterrogator == null) {
- _traceDeviceInterrogator = new TraceDeviceInfo(telephonyManager);
- } // end-if
-
- } // end-if
-
- // Setup Internal ProxyMessage Dispatcher
- synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) {
- // Ensure internalProxyMessageDispatcher is null
- if (_internalProxyMessageDispatcher != null) {
- _internalProxyMessageDispatcher.dispose();
- _internalProxyMessageDispatcher = null;
- }
-
- _internalProxyMessageDispatcher = new ProxyMessageDispatcher<InternalProxyMessage>("INTERNAL_MESSAGE_DISPATCHER", new IDispatchingStrategy<InternalProxyMessage>() {
-
- @Override
- public void dispatch(InternalProxyMessage message) {
- dispatchInternalMessage(message);
- }
-
- @Override
- public void handleDispatchingError(String info, Exception ex) {
- handleErrorsFromInternalMessageDispatcher(info, ex);
- }
-
- @Override
- public void handleQueueingError(String info, Exception ex) {
- handleErrorsFromInternalMessageDispatcher(info, ex);
- }
- });
- }
-
- // Setup Incoming ProxyMessage Dispatcher
- synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) {
- // Ensure incomingProxyMessageDispatcher is null
- if (_incomingProxyMessageDispatcher != null) {
- _incomingProxyMessageDispatcher.dispose();
- _incomingProxyMessageDispatcher = null;
- }
-
- _incomingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("INCOMING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() {
- @Override
- public void dispatch(ProtocolMessage message) {
- dispatchIncomingMessage(message);
- }
-
- @Override
- public void handleDispatchingError(String info, Exception ex) {
- handleErrorsFromIncomingMessageDispatcher(info, ex);
- }
-
- @Override
- public void handleQueueingError(String info, Exception ex) {
- handleErrorsFromIncomingMessageDispatcher(info, ex);
- }
- });
- }
-
- // Setup Outgoing ProxyMessage Dispatcher
- synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) {
- // Ensure outgoingProxyMessageDispatcher is null
- if (_outgoingProxyMessageDispatcher != null) {
- _outgoingProxyMessageDispatcher.dispose();
- _outgoingProxyMessageDispatcher = null;
- }
-
- _outgoingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("OUTGOING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() {
- @Override
- public void dispatch(ProtocolMessage message) {
- dispatchOutgoingMessage(message);
- }
-
- @Override
- public void handleDispatchingError(String info, Exception ex) {
- handleErrorsFromOutgoingMessageDispatcher(info, ex);
- }
-
- @Override
- public void handleQueueingError(String info, Exception ex) {
- handleErrorsFromOutgoingMessageDispatcher(info, ex);
- }
- });
- }
-
- rpcResponseListeners = new SparseArray<OnRPCResponseListener>();
- rpcNotificationListeners = new SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>>();
- rpcRequestListeners = new SparseArray<CopyOnWriteArrayList<OnRPCRequestListener>>();
- rpcListeners = new SparseArray<CopyOnWriteArrayList<OnRPCListener>>();
-
- // Initialize the proxy
- try {
- initializeProxy();
- } catch (SdlException e) {
- // Couldn't initialize the proxy
- // Dispose threads and then rethrow exception
-
- if (_internalProxyMessageDispatcher != null) {
- _internalProxyMessageDispatcher.dispose();
- _internalProxyMessageDispatcher = null;
- }
- if (_incomingProxyMessageDispatcher != null) {
- _incomingProxyMessageDispatcher.dispose();
- _incomingProxyMessageDispatcher = null;
- }
- if (_outgoingProxyMessageDispatcher != null) {
- _outgoingProxyMessageDispatcher.dispose();
- _outgoingProxyMessageDispatcher = null;
- }
- throw e;
- }
-
- // Trace that ctor has fired
- SdlTrace.logProxyEvent("SdlProxy Created, instanceID=" + this.toString(), SDL_LIB_TRACE_KEY);
- }
-
- protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme,
- boolean callbackToUIThread, boolean preRegister, String sHashID, Boolean bEnableResume, BaseTransportConfig transportConfig)
- throws SdlException
- {
- performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp,
- sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, dayColorScheme, nightColorScheme, callbackToUIThread, preRegister, sHashID, bEnableResume, transportConfig);
- }
-
- /**
- * Constructor.
- *
- * @param listener Type of listener for this proxy base.
- * @param sdlProxyConfigurationResources Configuration resources for this proxy.
- * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not.
- * @param appName Client application name.
- * @param ttsName TTS name.
- * @param ngnMediaScreenAppName Media Screen Application name.
- * @param vrSynonyms List of synonyms.
- * @param isMediaApp Flag that indicates that client application if media application or not.
- * @param sdlMsgVersion Version of Sdl Message.
- * @param languageDesired Desired language.
- * @param hmiDisplayLanguageDesired Desired language for HMI.
- * @param appType Type of application.
- * @param appID Application identifier.
- * @param autoActivateID Auto activation identifier.
- * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not.
- * @param preRegister Flag that indicates that this proxy should be pre-registerd or not.
- * @param transportConfig Configuration of transport to be used by underlying connection.
- * @throws SdlException if there is an unrecoverable error class might throw an exception.
- */
- protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, boolean callbackToUIThread, boolean preRegister, BaseTransportConfig transportConfig)
- throws SdlException
- {
- performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp,
- sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, null, null, callbackToUIThread, preRegister, null, null, transportConfig);
- }
-
- /**
- * Constructor.
- *
- * @param listener Type of listener for this proxy base.
- * @param sdlProxyConfigurationResources Configuration resources for this proxy.
- * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not.
- * @param appName Client application name.
- * @param ttsName TTS name.
- * @param ngnMediaScreenAppName Media Screen Application name.
- * @param vrSynonyms List of synonyms.
- * @param isMediaApp Flag that indicates that client application if media application or not.
- * @param sdlMsgVersion Version of Sdl Message.
- * @param languageDesired Desired language.
- * @param hmiDisplayLanguageDesired Desired language for HMI.
- * @param appType Type of application.
- * @param appID Application identifier.
- * @param autoActivateID Auto activation identifier.
- * @param dayColorScheme Day color scheme.
- * @param dayColorScheme Night color scheme.
- * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not.
- * @param preRegister Flag that indicates that this proxy should be pre-registerd or not.
- * @param transportConfig Configuration of transport to be used by underlying connection.
- * @throws SdlException if there is an unrecoverable error class might throw an exception.
- */
- protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme,
- boolean callbackToUIThread, boolean preRegister, BaseTransportConfig transportConfig)
- throws SdlException
- {
- performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp,
- sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, dayColorScheme, nightColorScheme, callbackToUIThread, preRegister, null, null, transportConfig);
- }
-
- private Intent createBroadcastIntent()
- {
- Intent sendIntent = new Intent();
- sendIntent.setAction("com.smartdevicelink.broadcast");
- sendIntent.putExtra("APP_NAME", this._applicationName);
- sendIntent.putExtra("APP_ID", this._appID);
- sendIntent.putExtra("RPC_NAME", "");
- sendIntent.putExtra("TYPE", "");
- sendIntent.putExtra("SUCCESS", true);
- sendIntent.putExtra("CORRID", 0);
- sendIntent.putExtra("FUNCTION_NAME", "");
- sendIntent.putExtra("COMMENT1", "");
- sendIntent.putExtra("COMMENT2", "");
- sendIntent.putExtra("COMMENT3", "");
- sendIntent.putExtra("COMMENT4", "");
- sendIntent.putExtra("COMMENT5", "");
- sendIntent.putExtra("COMMENT6", "");
- sendIntent.putExtra("COMMENT7", "");
- sendIntent.putExtra("COMMENT8", "");
- sendIntent.putExtra("COMMENT9", "");
- sendIntent.putExtra("COMMENT10", "");
- sendIntent.putExtra("DATA", "");
- sendIntent.putExtra("SHOW_ON_UI", true);
- return sendIntent;
- }
- private void updateBroadcastIntent(Intent sendIntent, String sKey, String sValue)
- {
- if (sValue == null) sValue = "";
- sendIntent.putExtra(sKey, sValue);
- }
- private void updateBroadcastIntent(Intent sendIntent, String sKey, boolean bValue)
- {
- sendIntent.putExtra(sKey, bValue);
- }
- private void updateBroadcastIntent(Intent sendIntent, String sKey, int iValue)
- {
- sendIntent.putExtra(sKey, iValue);
- }
-
- private Service getService()
- {
- try {
- Service myService = null;
- if (_proxyListener != null && _proxyListener instanceof Service) {
- myService = (Service) _proxyListener;
- } else if (_appService != null) {
- myService = _appService;
- } else if (_appContext != null && _appContext instanceof Service) {
- myService = (Service) _appContext;
- }
- return myService;
- } catch (Exception ex){
- return null;
- }
- }
-
- private void sendBroadcastIntent(Intent sendIntent)
- {
- Service myService = null;
- if (_proxyListener != null && _proxyListener instanceof Service)
- {
- myService = (Service) _proxyListener;
- }
- else if (_appService != null)
- {
- myService = _appService;
- }
- Context myContext;
- if (myService != null){
- myContext = myService.getApplicationContext();
- } else if (_appContext != null){
- myContext = _appContext;
- }
- else
- {
- return;
- }
- try
- {
- if (myContext != null) myContext.sendBroadcast(sendIntent);
- }
- catch(Exception ex)
- {
- //If the service or context has become unavailable unexpectedly, catch the exception and move on -- no broadcast log will occur.
- }
- }
-
- private HttpURLConnection getURLConnection(Headers myHeader, String sURLString, int Timeout, int iContentLen)
- {
- String sContentType = "application/json";
- int CONNECTION_TIMEOUT = Timeout * 1000;
- int READ_TIMEOUT = Timeout * 1000;
- boolean bDoOutput = true;
- boolean bDoInput = true;
- boolean bUsesCaches = false;
- String sRequestMeth = "POST";
-
- boolean bInstFolRed = false;
- String sCharSet = "utf-8";
- int iContentLength = iContentLen;
-
- URL url;
- HttpURLConnection urlConnection;
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "getURLConnection");
- updateBroadcastIntent(sendIntent, "COMMENT1", "Actual Content Length: " + iContentLen);
-
- if (myHeader != null)
- {
- //if the header isn't null, use it and replace the hardcoded params
- int iTimeout;
- int iReadTimeout;
- sContentType = myHeader.getContentType();
- iTimeout = myHeader.getConnectTimeout();
- bDoOutput = myHeader.getDoOutput();
- bDoInput = myHeader.getDoInput();
- bUsesCaches = myHeader.getUseCaches();
- sRequestMeth = myHeader.getRequestMethod();
- iReadTimeout = myHeader.getReadTimeout();
- bInstFolRed = myHeader.getInstanceFollowRedirects();
- sCharSet = myHeader.getCharset();
- iContentLength = myHeader.getContentLength();
- CONNECTION_TIMEOUT = iTimeout*1000;
- READ_TIMEOUT = iReadTimeout*1000;
- updateBroadcastIntent(sendIntent, "COMMENT2", "\nHeader Defined Content Length: " + iContentLength);
- }
-
- try
- {
- url = new URL(sURLString);
- urlConnection = (HttpURLConnection) url.openConnection();
- urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
- urlConnection.setDoOutput(bDoOutput);
- urlConnection.setDoInput(bDoInput);
- urlConnection.setRequestMethod(sRequestMeth);
- urlConnection.setReadTimeout(READ_TIMEOUT);
- urlConnection.setInstanceFollowRedirects(bInstFolRed);
- urlConnection.setRequestProperty("Content-Type", sContentType);
- urlConnection.setRequestProperty("charset", sCharSet);
- urlConnection.setRequestProperty("Content-Length", "" + Integer.toString(iContentLength));
- urlConnection.setUseCaches(bUsesCaches);
- return urlConnection;
- }
- catch (Exception e)
- {
- return null;
- }
- finally
- {
- sendBroadcastIntent(sendIntent);
- }
- }
-
-
- private void sendOnSystemRequestToUrl(OnSystemRequest msg)
- {
- Intent sendIntent = createBroadcastIntent();
- Intent sendIntent2 = createBroadcastIntent();
-
- HttpURLConnection urlConnection = null;
- boolean bLegacy = false;
-
- String sURLString;
- if (!getPoliciesURL().equals("")) {
- sURLString = sPoliciesURL;
- } else {
- sURLString = msg.getUrl();
- }
-
- Integer iTimeout = msg.getTimeout();
-
- if (iTimeout == null)
- iTimeout = 2000;
-
- Headers myHeader = msg.getHeader();
-
- RequestType requestType = msg.getRequestType();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "sendOnSystemRequestToUrl");
- updateBroadcastIntent(sendIntent, "COMMENT5", "\r\nCloud URL: " + sURLString);
-
- try
- {
- if (myHeader == null) {
- updateBroadcastIntent(sendIntent, "COMMENT7", "\r\nHTTPRequest Header is null");
- }
-
- String sBodyString = msg.getBody();
-
- JSONObject jsonObjectToSendToServer;
- String valid_json = "";
- int length;
- if (sBodyString == null)
- {
- if(requestType == RequestType.HTTP ){
- length = msg.getBulkData().length;
- Intent sendIntent3 = createBroadcastIntent();
- updateBroadcastIntent(sendIntent3, "FUNCTION_NAME", "replace");
- updateBroadcastIntent(sendIntent3, "COMMENT1", "Valid Json length before replace: " + length);
- sendBroadcastIntent(sendIntent3);
-
- }else{
- List<String> legacyData = msg.getLegacyData();
- JSONArray jsonArrayOfSdlPPackets = new JSONArray(legacyData);
- jsonObjectToSendToServer = new JSONObject();
- jsonObjectToSendToServer.put("data", jsonArrayOfSdlPPackets);
- bLegacy = true;
- updateBroadcastIntent(sendIntent, "COMMENT6", "\r\nLegacy SystemRequest: true");
- valid_json = jsonObjectToSendToServer.toString().replace("\\", "");
- length = valid_json.getBytes("UTF-8").length;
- }
- }
- else
- {
- Intent sendIntent3 = createBroadcastIntent();
- updateBroadcastIntent(sendIntent3, "FUNCTION_NAME", "replace");
- updateBroadcastIntent(sendIntent3, "COMMENT1", "Valid Json length before replace: " + sBodyString.getBytes("UTF-8").length);
- sendBroadcastIntent(sendIntent3);
- valid_json = sBodyString.replace("\\", "");
- length = valid_json.getBytes("UTF-8").length;
- }
-
- urlConnection = getURLConnection(myHeader, sURLString, iTimeout, length);
-
- if (urlConnection == null)
- {
- Log.i(TAG, "urlConnection is null, check RPC input parameters");
- updateBroadcastIntent(sendIntent, "COMMENT2", "urlConnection is null, check RPC input parameters");
- return;
- }
-
- DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
- if(requestType == RequestType.HTTP){
- wr.write(msg.getBulkData());
- }else{
- wr.writeBytes(valid_json);
- }
-
- wr.flush();
- wr.close();
-
-
- long BeforeTime = System.currentTimeMillis();
- long AfterTime = System.currentTimeMillis();
- final long roundtriptime = AfterTime - BeforeTime;
-
- updateBroadcastIntent(sendIntent, "COMMENT4", " Round trip time: " + roundtriptime);
- updateBroadcastIntent(sendIntent, "COMMENT1", "Received response from cloud, response code=" + urlConnection.getResponseCode() + " ");
-
- int iResponseCode = urlConnection.getResponseCode();
-
- if (iResponseCode != HttpURLConnection.HTTP_OK)
- {
- Log.i(TAG, "Response code not HTTP_OK, returning from sendOnSystemRequestToUrl.");
- updateBroadcastIntent(sendIntent, "COMMENT2", "Response code not HTTP_OK, aborting request. ");
- return;
- }
-
- InputStream is = urlConnection.getInputStream();
- BufferedReader rd = new BufferedReader(new InputStreamReader(is));
- String line;
- StringBuilder response = new StringBuilder();
- while((line = rd.readLine()) != null)
- {
- response.append(line);
- response.append('\r');
- }
- rd.close();
- //We've read the body
- if(requestType == RequestType.HTTP){
- // Create the SystemRequest RPC to send to module.
- PutFile putFile = new PutFile();
- putFile.setFileType(FileType.JSON);
- putFile.setCorrelationID(POLICIES_CORRELATION_ID);
- putFile.setSdlFileName("response_data");
- putFile.setFileData(response.toString().getBytes("UTF-8"));
- putFile.setCRC(response.toString().getBytes());
- updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + response.toString());
-
- sendRPCMessagePrivate(putFile);
- Log.i("sendSystemRequestToUrl", "sent to sdl");
-
- updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.PUT_FILE.toString());
- updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
- updateBroadcastIntent(sendIntent2, "CORRID", putFile.getCorrelationID());
-
- }else{
- Vector<String> cloudDataReceived = new Vector<String>();
- final String dataKey = "data";
- // Convert the response to JSON
- JSONObject jsonResponse = new JSONObject(response.toString());
- if(jsonResponse.has(dataKey)){
- if (jsonResponse.get(dataKey) instanceof JSONArray)
- {
- JSONArray jsonArray = jsonResponse.getJSONArray(dataKey);
- for (int i=0; i<jsonArray.length(); i++)
- {
- if (jsonArray.get(i) instanceof String)
- {
- cloudDataReceived.add(jsonArray.getString(i));
- //Log.i("sendSystemRequestToUrl", "jsonArray.getString(i): " + jsonArray.getString(i));
- }
- }
- }
- else if (jsonResponse.get(dataKey) instanceof String)
- {
- cloudDataReceived.add(jsonResponse.getString(dataKey));
- //Log.i("sendSystemRequestToUrl", "jsonResponse.getString(data): " + jsonResponse.getString("data"));
- }
- }
- else
- {
- DebugTool.logError("sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
- //Log.i("sendSystemRequestToUrl", "sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
- return;
- }
-
- String sResponse = cloudDataReceived.toString();
-
- if (sResponse.length() > 512)
- {
- sResponse = sResponse.substring(0, 511);
- }
-
- updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + sResponse);
-
- // Send new SystemRequest to SDL
- SystemRequest mySystemRequest = null;
-
- if (bLegacy){
- if(cloudDataReceived != null) {
- mySystemRequest = new SystemRequest(true);
- mySystemRequest.setCorrelationID(getPoliciesReservedCorrelationID());
- mySystemRequest.setLegacyData(cloudDataReceived);
- }
- }else{
- if (response != null) {
- mySystemRequest = new SystemRequest();
- mySystemRequest.setRequestType(RequestType.PROPRIETARY);
- mySystemRequest.setCorrelationID(getPoliciesReservedCorrelationID());
- mySystemRequest.setBulkData(response.toString().getBytes());
- }
- }
-
- if (getIsConnected())
- {
- sendRPCMessagePrivate(mySystemRequest);
- Log.i("sendSystemRequestToUrl", "sent to sdl");
-
- updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
- updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
- updateBroadcastIntent(sendIntent2, "CORRID", mySystemRequest.getCorrelationID());
- }
- }
- }
- catch (SdlException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: Could not get data from JSONObject received.", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " SdlException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: Could not get data from JSONObject received."+ e);
- }
- catch (JSONException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: JSONException: ", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " JSONException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: JSONException: "+ e);
- }
- catch (UnsupportedEncodingException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: Could not encode string.", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " UnsupportedEncodingException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: Could not encode string."+ e);
- }
- catch (ProtocolException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: Could not set request method to post.", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " ProtocolException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: Could not set request method to post."+ e);
- }
- catch (MalformedURLException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " MalformedURLException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server."+ e);
- }
- catch (IOException e)
- {
- DebugTool.logError("sendSystemRequestToUrl: IOException: ", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " IOException while sending to cloud: IOException: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: IOException: "+ e);
- }
- catch (Exception e)
- {
- DebugTool.logError("sendSystemRequestToUrl: Unexpected Exception: ", e);
- updateBroadcastIntent(sendIntent, "COMMENT3", " Exception encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendSystemRequestToUrl: Unexpected Exception: " + e);
- }
- finally
- {
- sendBroadcastIntent(sendIntent);
- sendBroadcastIntent(sendIntent2);
-
- if (iFileCount < 10)
- iFileCount++;
- else
- iFileCount = 0;
-
- if(urlConnection != null)
- {
- urlConnection.disconnect();
- }
- }
- }
-
- private int getPoliciesReservedCorrelationID() {
- return POLICIES_CORRELATION_ID;
- }
-
- // Test correlationID
- private boolean isCorrelationIDProtected(Integer correlationID) {
- return correlationID != null &&
- (HEARTBEAT_CORRELATION_ID == correlationID
- || REGISTER_APP_INTERFACE_CORRELATION_ID == correlationID
- || UNREGISTER_APP_INTERFACE_CORRELATION_ID == correlationID
- || POLICIES_CORRELATION_ID == correlationID);
-
- }
-
- // Protected isConnected method to allow legacy proxy to poll isConnected state
- public Boolean getIsConnected() {
- return sdlSession != null && sdlSession.getIsConnected();
- }
-
-
- /**
- * Returns whether the application is registered in SDL. Note: for testing
- * purposes, it's possible that the connection is established, but the
- * application is not registered.
- *
- * @return true if the application is registered in SDL
- */
- public Boolean getAppInterfaceRegistered() {
- return _appInterfaceRegisterd;
- }
-
- // Function to initialize new proxy connection
- public void initializeProxy() throws SdlException {
- // Reset all of the flags and state variables
- _haveReceivedFirstNonNoneHMILevel = false;
- _haveReceivedFirstFocusLevel = false;
- _haveReceivedFirstFocusLevelFull = false;
- _appInterfaceRegisterd = _preRegisterd;
-
- _putFileListenerList.clear();
-
- _sdlIntefaceAvailablity = SdlInterfaceAvailability.SDL_INTERFACE_UNAVAILABLE;
-
- //Initialize _systemCapabilityManager here.
- _systemCapabilityManager = new SystemCapabilityManager(_internalInterface);
- // Setup SdlConnection
- synchronized(CONNECTION_REFERENCE_LOCK) {
-
- //Handle legacy USB connections
- if(_transportConfig != null
- && TransportType.USB.equals(_transportConfig.getTransportType())){
- //A USB transport config was provided
- USBTransportConfig usbTransportConfig = (USBTransportConfig)_transportConfig;
- if(usbTransportConfig.getUsbAccessory() == null){
- DebugTool.logInfo("Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service");
- //The accessory was null which means it came from a router service
- MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(),_appID);
- multiplexTransportConfig.setRequiresHighBandwidth(true);
- multiplexTransportConfig.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF);
- multiplexTransportConfig.setPrimaryTransports(Collections.singletonList(TransportType.USB));
- multiplexTransportConfig.setSecondaryTransports(new ArrayList<TransportType>());
- _transportConfig = multiplexTransportConfig;
- }
- }
-
- if(_transportConfig.getTransportType().equals(TransportType.MULTIPLEX)){
- this.sdlSession = new SdlSession2(_interfaceBroker,(MultiplexTransportConfig)_transportConfig);
- }else{
- this.sdlSession = SdlSession.createSession((byte)getProtocolVersion().getMajor(),_interfaceBroker, _transportConfig);
- }
- }
-
- synchronized(CONNECTION_REFERENCE_LOCK) {
- this.sdlSession.startSession();
- sendTransportBroadcast();
- }
- }
- /**
- * This method will fake the multiplex connection event
- */
- @SuppressWarnings("unused")
- public void forceOnConnected(){
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (sdlSession != null) {
- Log.d(TAG, "Forcing on connected.... might actually need this"); //FIXME
- /*if(sdlSession.getSdlConnection()==null){ //There is an issue when switching from v1 to v2+ where the connection is closed. So we restart the session during this call.
- try {
- sdlSession.startSession();
- } catch (SdlException e) {
- e.printStackTrace();
- }
- }
- sdlSession.getSdlConnection().forceHardwareConnectEvent(TransportType.BLUETOOTH);
- */
- }
- }
- }
-
- public void sendTransportBroadcast()
- {
- if (sdlSession == null || _transportConfig == null) return;
-
- String sTransComment = sdlSession.getBroadcastComment(_transportConfig);
-
- if (sTransComment == null || sTransComment.equals("")) return;
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "initializeProxy");
- updateBroadcastIntent(sendIntent, "COMMENT1", sTransComment);
- sendBroadcastIntent(sendIntent);
- }
-
-
- /**
- * Public method to enable the siphon transport
- */
- @SuppressWarnings("unused")
- public void enableSiphonDebug() {
-
- short enabledPortNumber = SiphonServer.enableSiphonServer();
- String sSiphonPortNumber = "Enabled Siphon Port Number: " + enabledPortNumber;
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "enableSiphonDebug");
- updateBroadcastIntent(sendIntent, "COMMENT1", sSiphonPortNumber);
- sendBroadcastIntent(sendIntent);
- }
-
-
-
- /**
- * Public method to disable the Siphon Trace Server
- */
- @SuppressWarnings("unused")
- public void disableSiphonDebug() {
-
- short disabledPortNumber = SiphonServer.disableSiphonServer();
- if (disabledPortNumber != -1) {
- String sSiphonPortNumber = "Disabled Siphon Port Number: " + disabledPortNumber;
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "disableSiphonDebug");
- updateBroadcastIntent(sendIntent, "COMMENT1", sSiphonPortNumber);
- sendBroadcastIntent(sendIntent);
- }
- }
-
-
-
- /**
- * Public method to enable the Debug Tool
- */
- public static void enableDebugTool() {
- DebugTool.enableDebugTool();
- }
-
- /**
- * Public method to disable the Debug Tool
- */
- public static void disableDebugTool() {
- DebugTool.disableDebugTool();
- }
-
- /**
- * Public method to determine Debug Tool enabled
- */
- @SuppressWarnings("BooleanMethodIsAlwaysInverted")
- public static boolean isDebugEnabled() {
- return DebugTool.isDebugEnabled();
- }
-
-
- /**
- * Check to see if it a transport is available to perform audio streaming.
- * <br><strong>NOTE:</strong> This is only for the audio streaming service, not regular
- * streaming of media playback.
- * @return true if there is either an audio streaming supported
- * transport currently connected or a transport is
- * available to connect with. false if there is no
- * transport connected to support audio streaming and
- * no possibility in the foreseeable future.
- */
- public boolean isAudioStreamTransportAvailable(){
- return sdlSession!= null && sdlSession.isTransportForServiceAvailable(SessionType.PCM);
- }
-
- /**
- * Check to see if it a transport is available to perform video streaming.
-
- * @return true if there is either an video streaming supported
- * transport currently connected or a transport is
- * available to connect with. false if there is no
- * transport connected to support video streaming and
- * no possibility in the foreseeable future.
- */
- public boolean isVideoStreamTransportAvailable(){
- return sdlSession!= null && sdlSession.isTransportForServiceAvailable(SessionType.NAV);
- }
-
-
- @SuppressWarnings("unused")
- @Deprecated
- public void close() throws SdlException {
- dispose();
- }
-
- @SuppressWarnings("UnusedParameters")
- private void cleanProxy(SdlDisconnectedReason disconnectedReason) throws SdlException {
- if (disconnectedReason == SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED || disconnectedReason == SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED){
- notifyProxyClosed(disconnectedReason.toString(), null, disconnectedReason);
- sdlSession.resetSession();
- }
- try {
-
- // ALM Specific Cleanup
- if (_advancedLifecycleManagementEnabled) {
- _sdlConnectionState = SdlConnectionState.SDL_DISCONNECTED;
-
- firstTimeFull = true;
-
- // Should we wait for the interface to be unregistered?
- Boolean waitForInterfaceUnregistered = false;
- // Unregister app interface
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (getIsConnected() && getAppInterfaceRegistered()) {
- waitForInterfaceUnregistered = true;
- unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID);
- }
- }
-
- // Wait for the app interface to be unregistered
- if (waitForInterfaceUnregistered) {
- synchronized(APP_INTERFACE_REGISTERED_LOCK) {
- try {
- APP_INTERFACE_REGISTERED_LOCK.wait(3000);
- } catch (InterruptedException e) {
- // Do nothing
- }
- }
- }
- }
-
- if(rpcResponseListeners != null){
- rpcResponseListeners.clear();
- }
- if(rpcNotificationListeners != null){
- rpcNotificationListeners.clear();
- }
-
- // Clean up SDL Connection
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (sdlSession != null) sdlSession.close();
- }
- } finally {
- SdlTrace.logProxyEvent("SdlProxy cleaned.", SDL_LIB_TRACE_KEY);
- }
- }
-
- /**
- * Terminates the App's Interface Registration, closes the transport connection, ends the protocol session, and frees any resources used by the proxy.
- */
- public void dispose() throws SdlException
- {
- if (_proxyDisposed) {
- throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
- }
-
- _proxyDisposed = true;
-
- SdlTrace.logProxyEvent("Application called dispose() method.", SDL_LIB_TRACE_KEY);
-
- try{
- // Clean the proxy
- cleanProxy(SdlDisconnectedReason.APPLICATION_REQUESTED_DISCONNECT);
-
- // Close IncomingProxyMessageDispatcher thread
- synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_incomingProxyMessageDispatcher != null) {
- _incomingProxyMessageDispatcher.dispose();
- _incomingProxyMessageDispatcher = null;
- }
- }
-
- // Close OutgoingProxyMessageDispatcher thread
- synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_outgoingProxyMessageDispatcher != null) {
- _outgoingProxyMessageDispatcher.dispose();
- _outgoingProxyMessageDispatcher = null;
- }
- }
-
- // Close InternalProxyMessageDispatcher thread
- synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_internalProxyMessageDispatcher != null) {
- _internalProxyMessageDispatcher.dispose();
- _internalProxyMessageDispatcher = null;
- }
- }
-
- _traceDeviceInterrogator = null;
-
- rpcResponseListeners = null;
-
- } finally {
- SdlTrace.logProxyEvent("SdlProxy disposed.", SDL_LIB_TRACE_KEY);
- }
- } // end-method
-
-
- private final static Object CYCLE_LOCK = new Object();
-
- private boolean _cycling = false;
-
- // Method to cycle the proxy, only called in ALM
- protected void cycleProxy(SdlDisconnectedReason disconnectedReason) {
- if (_cycling) return;
-
- synchronized(CYCLE_LOCK)
- {
- try{
- _cycling = true;
- cleanProxy(disconnectedReason);
- initializeProxy();
- if(!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason)
- && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(disconnectedReason)){//We don't want to alert higher if we are just cycling for legacy bluetooth
- notifyProxyClosed("Sdl Proxy Cycled", new SdlException("Sdl Proxy Cycled", SdlExceptionCause.SDL_PROXY_CYCLED), disconnectedReason);
- }
- }
- catch (SdlException e) {
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "cycleProxy");
- updateBroadcastIntent(sendIntent, "COMMENT1", "Proxy cycled, exception cause: " + e.getSdlExceptionCause());
- sendBroadcastIntent(sendIntent);
-
- switch(e.getSdlExceptionCause()) {
- case BLUETOOTH_DISABLED:
- notifyProxyClosed("Bluetooth is disabled. Bluetooth must be enabled to connect to SDL. Reattempt a connection once Bluetooth is enabled.",
- new SdlException("Bluetooth is disabled. Bluetooth must be enabled to connect to SDL. Reattempt a connection once Bluetooth is enabled.", SdlExceptionCause.BLUETOOTH_DISABLED), SdlDisconnectedReason.BLUETOOTH_DISABLED);
- break;
- case BLUETOOTH_ADAPTER_NULL:
- notifyProxyClosed("Cannot locate a Bluetooth adapater. A SDL connection is impossible on this device until a Bluetooth adapter is added.",
- new SdlException("Cannot locate a Bluetooth adapater. A SDL connection is impossible on this device until a Bluetooth adapter is added.", SdlExceptionCause.BLUETOOTH_ADAPTER_NULL), SdlDisconnectedReason.BLUETOOTH_ADAPTER_ERROR);
- break;
- default :
- notifyProxyClosed("Cycling the proxy failed.", e, SdlDisconnectedReason.GENERIC_ERROR);
- break;
- }
- } catch (Exception e) {
- notifyProxyClosed("Cycling the proxy failed.", e, SdlDisconnectedReason.GENERIC_ERROR);
- }
- _cycling = false;
- }
- }
-
-
-
- /************* Functions used by the Message Dispatching Queues ****************/
- private void dispatchIncomingMessage(ProtocolMessage message) {
- try{
- // Dispatching logic
- if (message.getSessionType().equals(SessionType.RPC)
- ||message.getSessionType().equals(SessionType.BULK_DATA) ) {
- try {
- if (protocolVersion!= null && protocolVersion.getMajor() == 1 && message.getVersion() > 1) {
- if(sdlSession != null
- && sdlSession.getProtocolVersion()!= null
- && sdlSession.getProtocolVersion().getMajor() > 1){
- setProtocolVersion(sdlSession.getProtocolVersion());
- }else{
- setProtocolVersion(new Version(message.getVersion(),0,0));
- }
- }
-
- Hashtable<String, Object> hash = new Hashtable<String, Object>();
- if (protocolVersion!= null && protocolVersion.getMajor() > 1) {
- Hashtable<String, Object> hashTemp = new Hashtable<String, Object>();
- hashTemp.put(RPCMessage.KEY_CORRELATION_ID, message.getCorrID());
- if (message.getJsonSize() > 0) {
- final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData());
- //hashTemp.put(Names.parameters, mhash.get(Names.parameters));
- if (mhash != null) {
- hashTemp.put(RPCMessage.KEY_PARAMETERS, mhash);
- }
- }
-
- String functionName = FunctionID.getFunctionName(message.getFunctionID());
- if (functionName != null) {
- hashTemp.put(RPCMessage.KEY_FUNCTION_NAME, functionName);
- } else {
- DebugTool.logWarning("Dispatch Incoming Message - function name is null unknown RPC. FunctionId: " + message.getFunctionID());
- return;
- }
- if (message.getRPCType() == 0x00) {
- hash.put(RPCMessage.KEY_REQUEST, hashTemp);
- } else if (message.getRPCType() == 0x01) {
- hash.put(RPCMessage.KEY_RESPONSE, hashTemp);
- } else if (message.getRPCType() == 0x02) {
- hash.put(RPCMessage.KEY_NOTIFICATION, hashTemp);
- }
- if (message.getBulkData() != null) hash.put(RPCStruct.KEY_BULK_DATA, message.getBulkData());
- if (message.getPayloadProtected()) hash.put(RPCStruct.KEY_PROTECTED, true);
- } else {
- hash = JsonRPCMarshaller.unmarshall(message.getData());
- }
- handleRPCMessage(hash);
- } catch (final Exception excp) {
- DebugTool.logError("Failure handling protocol message: " + excp.toString(), excp);
- passErrorToProxyListener("Error handing incoming protocol message.", excp);
- } // end-catch
- } //else { Handle other protocol message types here}
- } catch (final Exception e) {
- // Pass error to application through listener
- DebugTool.logError("Error handing proxy event.", e);
- passErrorToProxyListener("Error handing incoming protocol message.", e);
- }
- }
-
- /**
- * Get the SDL protocol spec version being used
- * @return Version of the protocol spec
- */
- public @NonNull Version getProtocolVersion(){
- if(this.protocolVersion == null){
- this.protocolVersion = new Version(1,0,0);
- }
- return this.protocolVersion;
- }
-
- private void setProtocolVersion(@NonNull Version version) {
- this.protocolVersion = version;
- }
-
- public String serializeJSON(RPCMessage msg)
- {
- try
- {
- return msg.serializeJSON((byte)this.getProtocolVersion().getMajor()).toString(2);
- }
- catch (final Exception e)
- {
- DebugTool.logError("Error handing proxy event.", e);
- passErrorToProxyListener("Error serializing message.", e);
- return null;
- }
- }
-
- private void handleErrorsFromIncomingMessageDispatcher(String info, Exception e) {
- passErrorToProxyListener(info, e);
- }
-
- private void dispatchOutgoingMessage(ProtocolMessage message) {
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (sdlSession != null) {
- sdlSession.sendMessage(message);
- }
- }
- SdlTrace.logProxyEvent("SdlProxy sending Protocol Message: " + message.toString(), SDL_LIB_TRACE_KEY);
- }
-
- private void handleErrorsFromOutgoingMessageDispatcher(String info, Exception e) {
- passErrorToProxyListener(info, e);
- }
-
- void dispatchInternalMessage(final InternalProxyMessage message) {
- try{
- switch (message.getFunctionName()) {
- case InternalProxyMessage.OnProxyError: {
- final OnError msg = (OnError) message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onError(msg.getInfo(), msg.getException());
- }
- });
- } else {
- _proxyListener.onError(msg.getInfo(), msg.getException());
- }
- break;
- }
- case InternalProxyMessage.OnServiceEnded: {
- final OnServiceEnded msg = (OnServiceEnded) message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onServiceEnded(msg);
- }
- });
- } else {
- _proxyListener.onServiceEnded(msg);
- }
- break;
- }
- case InternalProxyMessage.OnServiceNACKed: {
- final OnServiceNACKed msg = (OnServiceNACKed) message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onServiceNACKed(msg);
- }
- });
- } else {
- _proxyListener.onServiceNACKed(msg);
- }
-
- /* *************Start Legacy Specific Call-backs************/
- break;
- }
- case InternalProxyMessage.OnProxyOpened:
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- ((IProxyListener) _proxyListener).onProxyOpened();
- }
- });
- } else {
- ((IProxyListener) _proxyListener).onProxyOpened();
- }
- break;
- case InternalProxyMessage.OnProxyClosed: {
- final OnProxyClosed msg = (OnProxyClosed) message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
- }
- });
- } else {
- _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
- }
- /* ***************End Legacy Specific Call-backs************/
- break;
- }
- default:
- // Diagnostics
- SdlTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.", SDL_LIB_TRACE_KEY);
- DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.");
- break;
- }
-
- SdlTrace.logProxyEvent("Proxy fired callback: " + message.getFunctionName(), SDL_LIB_TRACE_KEY);
- } catch(final Exception e) {
- // Pass error to application through listener
- DebugTool.logError("Error handing proxy event.", e);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onError("Error handing proxy event.", e);
- }
- });
- } else {
- _proxyListener.onError("Error handing proxy event.", e);
- }
- }
- }
-
- private void handleErrorsFromInternalMessageDispatcher(String info, Exception e) {
- DebugTool.logError(info, e);
- // This error cannot be passed to the user, as it indicates an error
- // in the communication between the proxy and the application.
-
- DebugTool.logError("InternalMessageDispatcher failed.", e);
-
- // Note, this is the only place where the _proxyListener should be referenced asdlhronously,
- // with an error on the internalMessageDispatcher, we have no other reliable way of
- // communicating with the application.
- notifyProxyClosed("Proxy callback dispatcher is down. Proxy instance is invalid.", e, SdlDisconnectedReason.GENERIC_ERROR);
- _proxyListener.onError("Proxy callback dispatcher is down. Proxy instance is invalid.", e);
- }
- /************* END Functions used by the Message Dispatching Queues ****************/
-
- // Private sendRPCMessagePrivate method. All RPCMessages are funneled through this method after error checking.
- protected void sendRPCMessagePrivate(RPCMessage message) throws SdlException {
- try {
- SdlTrace.logRPCEvent(InterfaceActivityDirection.Transmit, message, SDL_LIB_TRACE_KEY);
-
- //FIXME this is temporary until the next major release of the library where OK is removed
- if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) {
- RPCRequest request = (RPCRequest) message;
- if (FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName())
- || FunctionID.UNSUBSCRIBE_BUTTON.toString().equals(request.getFunctionName())
- || FunctionID.BUTTON_PRESS.toString().equals(request.getFunctionName())) {
-
- ButtonName buttonName = (ButtonName) request.getObject(ButtonName.class, SubscribeButton.KEY_BUTTON_NAME);
-
-
- if (rpcSpecVersion != null) {
- if (rpcSpecVersion.getMajor() < 5) {
-
- if (ButtonName.PLAY_PAUSE.equals(buttonName)) {
- request.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.OK);
- }
- } else { //Newer than version 5.0.0
- if (ButtonName.OK.equals(buttonName)) {
- RPCRequest request2 = new RPCRequest(request);
- request2.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.PLAY_PAUSE);
- request2.setOnRPCResponseListener(request.getOnRPCResponseListener());
- sendRPCMessagePrivate(request2);
- return;
- }
- }
- }
-
- }
- }
-
- message.format(rpcSpecVersion,true);
- byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor());
-
- ProtocolMessage pm = new ProtocolMessage();
- pm.setData(msgBytes);
- pm.setMessageType(MessageType.RPC);
- pm.setSessionType(SessionType.RPC);
- pm.setFunctionID(FunctionID.getFunctionId(message.getFunctionName()));
- pm.setPayloadProtected(message.isPayloadProtected());
-
- if (sdlSession != null) {
- pm.setSessionID(sdlSession.getSessionId());
- }
-
- if (message.getBulkData() != null) {
- pm.setBulkData(message.getBulkData());
- }
-
-
- if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { // Request Specifics
- pm.setRPCType((byte)0x00);
- RPCRequest request = (RPCRequest) message;
- if (request.getCorrelationID() == null) {
- //Log error here
- throw new SdlException("CorrelationID cannot be null. RPC: " + request.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT);
- } else {
- pm.setCorrID(request.getCorrelationID());
- }
- if (request.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())) {
- pm.setPriorityCoefficient(1);
- }
- } else if (message.getMessageType().equals(RPCMessage.KEY_RESPONSE)) { // Response Specifics
- pm.setRPCType((byte)0x01);
- RPCResponse response = (RPCResponse) message;
- if (response.getCorrelationID() == null) {
- //Log error here
- throw new SdlException("CorrelationID cannot be null. RPC: " + response.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT);
- } else {
- pm.setCorrID(response.getCorrelationID());
- }
- } else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics
- pm.setRPCType((byte)0x02);
- } else {
- //Log error here
- throw new SdlException("RPC message is not a valid type", SdlExceptionCause.INVALID_ARGUMENT);
- }
-
- // Queue this outgoing message
- synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_outgoingProxyMessageDispatcher != null) {
- _outgoingProxyMessageDispatcher.queueMessage(pm);
- //Since the message is queued we can add it's listener to our list, if it is a Request
- if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) {
- RPCRequest request = (RPCRequest) message;
- OnRPCResponseListener listener = request.getOnRPCResponseListener();
- addOnRPCResponseListener(listener, request.getCorrelationID(), msgBytes.length);
- }
- }
- }
- } catch (OutOfMemoryError e) {
- SdlTrace.logProxyEvent("OutOfMemory exception while sending message " + message.getFunctionName(), SDL_LIB_TRACE_KEY);
- throw new SdlException("OutOfMemory exception while sending message " + message.getFunctionName(), e, SdlExceptionCause.INVALID_ARGUMENT);
- }
- }
-
- /**
- * Only call this method for a PutFile response. It will cause a class cast exception if not.
- * @param correlationId correlation id of the packet being updated
- * @param bytesWritten how many bytes were written
- * @param totalSize the total size in bytes
- */
- @SuppressWarnings("unused")
- public void onPacketProgress(int correlationId, long bytesWritten, long totalSize){
- synchronized(ON_UPDATE_LISTENER_LOCK){
- if(rpcResponseListeners !=null
- && rpcResponseListeners.indexOfKey(correlationId)>=0){
- ((OnPutFileUpdateListener)rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize);
- }
- }
-
- }
-
- /**
- * Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code,
- * <p>Will automatically remove the listener for the list of listeners on completion.
- * @param msg The RPCResponse message that was received
- * @return if a listener was called or not
- */
- @SuppressWarnings("UnusedReturnValue")
- private boolean onRPCResponseReceived(RPCResponse msg){
- synchronized(ON_UPDATE_LISTENER_LOCK){
- int correlationId = msg.getCorrelationID();
- if(rpcResponseListeners !=null
- && rpcResponseListeners.indexOfKey(correlationId)>=0){
- OnRPCResponseListener listener = rpcResponseListeners.get(correlationId);
- if(msg.getSuccess()){
- listener.onResponse(correlationId, msg);
- }else{
- listener.onError(correlationId, msg.getResultCode(), msg.getInfo());
- }
- rpcResponseListeners.remove(correlationId);
- return true;
- }
- return false;
- }
- }
-
-/**
- * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id
- * @param listener that will get called back when a response is received
- * @param correlationId of the RPCRequest that was sent
- * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored.
- */
- public void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){
- synchronized(ON_UPDATE_LISTENER_LOCK){
- if(rpcResponseListeners!=null
- && listener !=null){
- if(listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE){
- ((OnPutFileUpdateListener)listener).setTotalSize(totalSize);
- }
- listener.onStart(correlationId);
- rpcResponseListeners.put(correlationId, listener);
- }
- }
- }
-
- @SuppressWarnings("unused")
- public SparseArray<OnRPCResponseListener> getResponseListeners(){
- synchronized(ON_UPDATE_LISTENER_LOCK){
- return this.rpcResponseListeners;
- }
- }
-
- @SuppressWarnings("UnusedReturnValue")
- public boolean onRPCNotificationReceived(RPCNotification notification){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- CopyOnWriteArrayList<OnRPCNotificationListener> listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName()));
- if(listeners!=null && listeners.size()>0) {
- for (OnRPCNotificationListener listener : listeners) {
- listener.onNotified(notification);
- }
- return true;
- }
- return false;
- }
- }
-
- @SuppressWarnings("UnusedReturnValue")
- public boolean onRPCReceived(RPCMessage message){
- synchronized(RPC_LISTENER_LOCK){
- CopyOnWriteArrayList<OnRPCListener> listeners = rpcListeners.get(FunctionID.getFunctionId(message.getFunctionName()));
- if(listeners!=null && listeners.size()>0) {
- for (OnRPCListener listener : listeners) {
- listener.onReceived(message);
- }
- return true;
- }
- return false;
- }
- }
-
- @SuppressWarnings("UnusedReturnValue")
- public boolean onRPCRequestReceived(RPCRequest request){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- CopyOnWriteArrayList<OnRPCRequestListener> listeners = rpcRequestListeners.get(FunctionID.getFunctionId(request.getFunctionName()));
- if(listeners!=null && listeners.size()>0) {
- for (OnRPCRequestListener listener : listeners) {
- listener.onRequest(request);
- }
- return true;
- }
- return false;
- }
- }
-
- /**
- * This will ad a listener for the specific type of notification. As of now it will only allow
- * a single listener per notification function id
- * @param notificationId The notification type that this listener is designated for
- * @param listener The listener that will be called when a notification of the provided type is received
- */
- @SuppressWarnings("unused")
- public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- if(notificationId != null && listener != null){
- if(rpcNotificationListeners.indexOfKey(notificationId.getId()) < 0 ){
- rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList<OnRPCNotificationListener>());
- }
- rpcNotificationListeners.get(notificationId.getId()).add(listener);
- }
- }
- }
-
- /**
- * This will add a listener for the specific type of message. As of now it will only allow
- * a single listener per request function id
- * @param messageId The message type that this listener is designated for
- * @param listener The listener that will be called when a request of the provided type is received
- */
- @SuppressWarnings("unused")
- public void addOnRPCListener(FunctionID messageId, OnRPCListener listener){
- synchronized(RPC_LISTENER_LOCK){
- if(messageId != null && listener != null){
- if(rpcListeners.indexOfKey(messageId.getId()) < 0 ){
- rpcListeners.put(messageId.getId(),new CopyOnWriteArrayList<OnRPCListener>());
- }
- rpcListeners.get(messageId.getId()).add(listener);
- }
- }
- }
-
- public boolean removeOnRPCListener(FunctionID messageId, OnRPCListener listener){
- synchronized(RPC_LISTENER_LOCK){
- if(rpcListeners!= null
- && messageId != null
- && listener != null
- && rpcListeners.indexOfKey(messageId.getId()) >= 0){
- return rpcListeners.get(messageId.getId()).remove(listener);
- }
- }
- return false;
- }
-
- /**
- * This will add a listener for the specific type of request. As of now it will only allow
- * a single listener per request function id
- * @param requestId The request type that this listener is designated for
- * @param listener The listener that will be called when a request of the provided type is received
- */
- @SuppressWarnings("unused")
- public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- if(requestId != null && listener != null){
- if(rpcRequestListeners.indexOfKey(requestId.getId()) < 0 ){
- rpcRequestListeners.put(requestId.getId(),new CopyOnWriteArrayList<OnRPCRequestListener>());
- }
- rpcRequestListeners.get(requestId.getId()).add(listener);
- }
- }
- }
-
- /**
- * This method is no longer valid and will not remove the listener for the supplied notificaiton id
- * @param notificationId n/a
- * @see #removeOnRPCNotificationListener(FunctionID, OnRPCNotificationListener)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void removeOnRPCNotificationListener(FunctionID notificationId){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- //rpcNotificationListeners.delete(notificationId.getId());
- }
- }
-
- public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- if(rpcNotificationListeners!= null
- && notificationId != null
- && listener != null
- && rpcNotificationListeners.indexOfKey(notificationId.getId()) >= 0){
- return rpcNotificationListeners.get(notificationId.getId()).remove(listener);
- }
- }
- return false;
- }
-
- public boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){
- synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- if(rpcRequestListeners!= null
- && requestId != null
- && listener != null
- && rpcRequestListeners.indexOfKey(requestId.getId()) >= 0){
- return rpcRequestListeners.get(requestId.getId()).remove(listener);
- }
- }
- return false;
- }
-
- private void processRaiResponse(RegisterAppInterfaceResponse rai)
- {
- if (rai == null) return;
-
- this.raiResponse = rai;
-
- VehicleType vt = rai.getVehicleType();
- if (vt == null) return;
-
- String make = vt.getMake();
- if (make == null) return;
-
- if (_secList == null) return;
-
- SdlSecurityBase sec;
- Service svc = getService();
- SdlSecurityBase.setAppService(svc);
- if (svc != null && svc.getApplicationContext() != null){
- SdlSecurityBase.setContext(svc.getApplicationContext());
- } else {
- SdlSecurityBase.setContext(_appContext);
- }
-
- for (Class<? extends SdlSecurityBase> cls : _secList)
- {
- try
- {
- sec = cls.newInstance();
- }
- catch (Exception e)
- {
- continue;
- }
-
- if ( (sec != null) && (sec.getMakeList() != null) )
- {
- if (sec.getMakeList().contains(make))
- {
- setSdlSecurity(sec);
- sec.setAppId(_appID);
- if (sdlSession != null)
- sec.handleSdlSession(sdlSession);
- return;
- }
- }
- }
- }
-
- private void handleRPCMessage(Hashtable<String, Object> hash) {
-
- if (hash == null){
- DebugTool.logError("handleRPCMessage: hash is null, returning.");
- return;
- }
-
- RPCMessage rpcMsg = RpcConverter.convertTableToRpc(hash);
-
- if (rpcMsg == null){
- DebugTool.logError("handleRPCMessage: rpcMsg is null, returning.");
- return;
- }
-
- SdlTrace.logRPCEvent(InterfaceActivityDirection.Receive, rpcMsg, SDL_LIB_TRACE_KEY);
-
- String functionName = rpcMsg.getFunctionName();
- String messageType = rpcMsg.getMessageType();
-
- rpcMsg.format(rpcSpecVersion, true);
-
- onRPCReceived(rpcMsg); // Should only be called for internal use
-
- // Requests need to be listened for using the SDLManager's addOnRPCRequestListener method.
- // Requests are not supported by IProxyListenerBase
- if (messageType.equals(RPCMessage.KEY_REQUEST)) {
-
- onRPCRequestReceived((RPCRequest) rpcMsg);
-
- } else if (messageType.equals(RPCMessage.KEY_RESPONSE)) {
- // Check to ensure response is not from an internal message (reserved correlation ID)
- if (isCorrelationIDProtected((new RPCResponse(hash)).getCorrelationID())) {
- // This is a response generated from an internal message, it can be trapped here
- // The app should not receive a response for a request it did not send
- if ((new RPCResponse(hash)).getCorrelationID() == REGISTER_APP_INTERFACE_CORRELATION_ID
- && _advancedLifecycleManagementEnabled
- && functionName.equals(FunctionID.REGISTER_APP_INTERFACE.toString())) {
- final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (msg.getSuccess()) {
- _appInterfaceRegisterd = true;
- }
- processRaiResponse(msg);
-
- //Populate the system capability manager with the RAI response
- _systemCapabilityManager.parseRAIResponse(msg);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.REGISTER_APP_INTERFACE.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- sendBroadcastIntent(sendIntent);
-
- //_autoActivateIdReturned = msg.getAutoActivateID();
- /*Place holder for legacy support*/ _autoActivateIdReturned = "8675309";
- _prerecordedSpeech = msg.getPrerecordedSpeech();
- _sdlLanguage = msg.getLanguage();
- _hmiDisplayLanguage = msg.getHmiDisplayLanguage();
- _sdlMsgVersion = msg.getSdlMsgVersion();
- if(_sdlMsgVersion != null){
- rpcSpecVersion = new com.smartdevicelink.util.Version(_sdlMsgVersion.getMajorVersion(),_sdlMsgVersion.getMinorVersion(), _sdlMsgVersion.getPatchVersion());
- }else{
- rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION;
- }
-
- if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1){
- Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion));
- try {
- unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- try {
- cleanProxy(SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- return;
- }
-
- _vehicleType = msg.getVehicleType();
- _systemSoftwareVersion = msg.getSystemSoftwareVersion();
- _proxyVersionInfo = BuildConfig.VERSION_NAME;
- _iconResumed = msg.getIconResumed();
-
- if (_iconResumed == null){
- _iconResumed = false;
- }
-
- if (_bAppResumeEnabled)
- {
- if ( (_sdlMsgVersion.getMajorVersion() > 2) && (_lastHashID != null) && (msg.getSuccess()) && (msg.getResultCode() != Result.RESUME_FAILED) )
- _bResumeSuccess = true;
- else
- {
- _bResumeSuccess = false;
- _lastHashID = null;
- }
- }
- _diagModes = msg.getSupportedDiagModes();
-
- String sVersionInfo = "SDL Proxy Version: " + _proxyVersionInfo;
-
- if (!isDebugEnabled())
- {
- enableDebugTool();
- DebugTool.logInfo(sVersionInfo, false);
- disableDebugTool();
- }
- else
- DebugTool.logInfo(sVersionInfo, false);
-
- sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "RAI_RESPONSE");
- updateBroadcastIntent(sendIntent, "COMMENT1", sVersionInfo);
- sendBroadcastIntent(sendIntent);
-
- // Send onSdlConnected message in ALM
- _sdlConnectionState = SdlConnectionState.SDL_CONNECTED;
-
- // If registerAppInterface failed, exit with OnProxyUnusable
- if (!msg.getSuccess()) {
- notifyProxyClosed("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: ",
- new SdlException("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SdlExceptionCause.SDL_REGISTRATION_ERROR), SdlDisconnectedReason.SDL_REGISTRATION_ERROR);
- }
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
- });
- } else {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
- } else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID
- && functionName.equals(FunctionID.ON_ENCODED_SYNC_P_DATA.toString())) {
-
- Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Notification (Legacy)");
-
- final OnSystemRequest msg = new OnSystemRequest(hash);
-
- // If url is not null, then send to URL
- if ( (msg.getUrl() != null) )
- {
- // URL has data, attempt to post request to external server
- Thread handleOffboardTransmissionThread = new Thread() {
- @Override
- public void run() {
- sendOnSystemRequestToUrl(msg);
- }
- };
-
- handleOffboardTransmissionThread.start();
- }
- }
- else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID
- && functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) {
-
- Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Response (Legacy)");
- final SystemRequestResponse msg = new SystemRequestResponse(hash);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- sendBroadcastIntent(sendIntent);
- }
- else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID
- && functionName.equals(FunctionID.SYSTEM_REQUEST.toString())) {
- final SystemRequestResponse msg = new SystemRequestResponse(hash);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- updateBroadcastIntent(sendIntent, "DATA", serializeJSON(msg));
- sendBroadcastIntent(sendIntent);
- }
- else if (functionName.equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) {
- // UnregisterAppInterface
- _appInterfaceRegisterd = false;
- synchronized(APP_INTERFACE_REGISTERED_LOCK) {
- APP_INTERFACE_REGISTERED_LOCK.notify();
- }
- final UnregisterAppInterfaceResponse msg = new UnregisterAppInterfaceResponse(hash);
- msg.format(rpcSpecVersion, true);
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- sendBroadcastIntent(sendIntent);
- }
- return;
- }
-
- if (functionName.equals(FunctionID.REGISTER_APP_INTERFACE.toString())) {
- final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (msg.getSuccess()) {
- _appInterfaceRegisterd = true;
- }
- processRaiResponse(msg);
- //Populate the system capability manager with the RAI response
- _systemCapabilityManager.parseRAIResponse(msg);
-
- //_autoActivateIdReturned = msg.getAutoActivateID();
- /*Place holder for legacy support*/ _autoActivateIdReturned = "8675309";
- _prerecordedSpeech = msg.getPrerecordedSpeech();
- _sdlLanguage = msg.getLanguage();
- _hmiDisplayLanguage = msg.getHmiDisplayLanguage();
- _sdlMsgVersion = msg.getSdlMsgVersion();
- rpcSpecVersion = new com.smartdevicelink.util.Version(_sdlMsgVersion.getMajorVersion(),_sdlMsgVersion.getMinorVersion(), _sdlMsgVersion.getPatchVersion());
- _vehicleType = msg.getVehicleType();
- _systemSoftwareVersion = msg.getSystemSoftwareVersion();
- _proxyVersionInfo = BuildConfig.VERSION_NAME;
-
- if (_bAppResumeEnabled)
- {
- if ( (_sdlMsgVersion.getMajorVersion() > 2) && (_lastHashID != null) && (msg.getSuccess()) && (msg.getResultCode() != Result.RESUME_FAILED) )
- _bResumeSuccess = true;
- else
- {
- _bResumeSuccess = false;
- _lastHashID = null;
- }
- }
-
- _diagModes = msg.getSupportedDiagModes();
-
- if (!isDebugEnabled())
- {
- enableDebugTool();
- DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo);
- disableDebugTool();
- }
- else
- DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo);
-
- // RegisterAppInterface
- if (_advancedLifecycleManagementEnabled) {
-
- // Send onSdlConnected message in ALM
- _sdlConnectionState = SdlConnectionState.SDL_CONNECTED;
-
- // If registerAppInterface failed, exit with OnProxyUnusable
- if (!msg.getSuccess()) {
- notifyProxyClosed("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: ",
- new SdlException("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SdlExceptionCause.SDL_REGISTRATION_ERROR), SdlDisconnectedReason.SDL_REGISTRATION_ERROR);
- }
- } else {
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
- });
- } else {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
- }
- } else if (functionName.equals(FunctionID.SPEAK.toString())) {
- // SpeakResponse
-
- final SpeakResponse msg = new SpeakResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSpeakResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSpeakResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ALERT.toString())) {
- // AlertResponse
-
- final AlertResponse msg = new AlertResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onAlertResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onAlertResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SHOW.toString())) {
- // ShowResponse
-
- final ShowResponse msg = new ShowResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onShowResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onShowResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ADD_COMMAND.toString())) {
- // AddCommand
-
- final AddCommandResponse msg = new AddCommandResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onAddCommandResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onAddCommandResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.DELETE_COMMAND.toString())) {
- // DeleteCommandResponse
-
- final DeleteCommandResponse msg = new DeleteCommandResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDeleteCommandResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDeleteCommandResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ADD_SUB_MENU.toString())) {
- // AddSubMenu
-
- final AddSubMenuResponse msg = new AddSubMenuResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onAddSubMenuResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onAddSubMenuResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.DELETE_SUB_MENU.toString())) {
- // DeleteSubMenu
-
- final DeleteSubMenuResponse msg = new DeleteSubMenuResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDeleteSubMenuResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDeleteSubMenuResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SUBSCRIBE_BUTTON.toString())) {
- // SubscribeButton
-
- final SubscribeButtonResponse msg = new SubscribeButtonResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSubscribeButtonResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSubscribeButtonResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UNSUBSCRIBE_BUTTON.toString())) {
- // UnsubscribeButton
-
- final UnsubscribeButtonResponse msg = new UnsubscribeButtonResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onUnsubscribeButtonResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onUnsubscribeButtonResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_MEDIA_CLOCK_TIMER.toString())) {
- // SetMediaClockTimer
-
- final SetMediaClockTimerResponse msg = new SetMediaClockTimerResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetMediaClockTimerResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetMediaClockTimerResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) {
-
- final SystemRequestResponse msg = new SystemRequestResponse(hash);
- msg.format(rpcSpecVersion,true);
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- sendBroadcastIntent(sendIntent);
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSystemRequestResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSystemRequestResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.CREATE_INTERACTION_CHOICE_SET.toString())) {
- // CreateInteractionChoiceSet
-
- final CreateInteractionChoiceSetResponse msg = new CreateInteractionChoiceSetResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onCreateInteractionChoiceSetResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onCreateInteractionChoiceSetResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.DELETE_INTERACTION_CHOICE_SET.toString())) {
- // DeleteInteractionChoiceSet
-
- final DeleteInteractionChoiceSetResponse msg = new DeleteInteractionChoiceSetResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDeleteInteractionChoiceSetResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDeleteInteractionChoiceSetResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.PERFORM_INTERACTION.toString())) {
- // PerformInteraction
-
- final PerformInteractionResponse msg = new PerformInteractionResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onPerformInteractionResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onPerformInteractionResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_GLOBAL_PROPERTIES.toString())) {
- // SetGlobalPropertiesResponse
-
- final SetGlobalPropertiesResponse msg = new SetGlobalPropertiesResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetGlobalPropertiesResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetGlobalPropertiesResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.RESET_GLOBAL_PROPERTIES.toString())) {
- // ResetGlobalProperties
-
- final ResetGlobalPropertiesResponse msg = new ResetGlobalPropertiesResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onResetGlobalPropertiesResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onResetGlobalPropertiesResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) {
- // UnregisterAppInterface
-
- _appInterfaceRegisterd = false;
- synchronized(APP_INTERFACE_REGISTERED_LOCK) {
- APP_INTERFACE_REGISTERED_LOCK.notify();
- }
-
- final UnregisterAppInterfaceResponse msg = new UnregisterAppInterfaceResponse(hash);
- msg.format(rpcSpecVersion,true);
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE);
- updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess());
- updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo());
- updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString());
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- sendBroadcastIntent(sendIntent);
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
- });
- } else {
- if (_proxyListener instanceof IProxyListener) {
- ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg);
- }
- onRPCResponseReceived(msg);
- }
-
- notifyProxyClosed("UnregisterAppInterfaceResponse", null, SdlDisconnectedReason.APP_INTERFACE_UNREG);
- } else if (functionName.equals(FunctionID.GENERIC_RESPONSE.toString())) {
- // GenericResponse (Usually and error)
- final GenericResponse msg = new GenericResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGenericResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGenericResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SLIDER.toString())) {
- // Slider
- final SliderResponse msg = new SliderResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSliderResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSliderResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.PUT_FILE.toString())) {
- // PutFile
- final PutFileResponse msg = new PutFileResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onPutFileResponse(msg);
- onRPCResponseReceived(msg);
- notifyPutFileStreamResponse(msg);
- }
- });
- } else {
- _proxyListener.onPutFileResponse(msg);
- onRPCResponseReceived(msg);
- notifyPutFileStreamResponse(msg);
- }
- } else if (functionName.equals(FunctionID.DELETE_FILE.toString())) {
- // DeleteFile
- final DeleteFileResponse msg = new DeleteFileResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDeleteFileResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDeleteFileResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.LIST_FILES.toString())) {
- // ListFiles
- final ListFilesResponse msg = new ListFilesResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onListFilesResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onListFilesResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_APP_ICON.toString())) {
- // SetAppIcon
- final SetAppIconResponse msg = new SetAppIconResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetAppIconResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetAppIconResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SCROLLABLE_MESSAGE.toString())) {
- // ScrollableMessage
- final ScrollableMessageResponse msg = new ScrollableMessageResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onScrollableMessageResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onScrollableMessageResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.CHANGE_REGISTRATION.toString())) {
- // ChangeLanguageRegistration
- final ChangeRegistrationResponse msg = new ChangeRegistrationResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onChangeRegistrationResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onChangeRegistrationResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_DISPLAY_LAYOUT.toString())) {
- // SetDisplayLayout
- final SetDisplayLayoutResponse msg = new SetDisplayLayoutResponse(hash);
- msg.format(rpcSpecVersion,true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetDisplayLayoutResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetDisplayLayoutResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.PERFORM_AUDIO_PASS_THRU.toString())) {
- // PerformAudioPassThru
- final PerformAudioPassThruResponse msg = new PerformAudioPassThruResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onPerformAudioPassThruResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onPerformAudioPassThruResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.END_AUDIO_PASS_THRU.toString())) {
- // EndAudioPassThru
- final EndAudioPassThruResponse msg = new EndAudioPassThruResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onEndAudioPassThruResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onEndAudioPassThruResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SUBSCRIBE_VEHICLE_DATA.toString())) {
- // SubscribeVehicleData
- final SubscribeVehicleDataResponse msg = new SubscribeVehicleDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSubscribeVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSubscribeVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UNSUBSCRIBE_VEHICLE_DATA.toString())) {
- // UnsubscribeVehicleData
- final UnsubscribeVehicleDataResponse msg = new UnsubscribeVehicleDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onUnsubscribeVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onUnsubscribeVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_VEHICLE_DATA.toString())) {
- // GetVehicleData
- final GetVehicleDataResponse msg = new GetVehicleDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SUBSCRIBE_WAY_POINTS.toString())) {
- // SubscribeWayPoints
- final SubscribeWayPointsResponse msg = new SubscribeWayPointsResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSubscribeWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSubscribeWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UNSUBSCRIBE_WAY_POINTS.toString())) {
- // UnsubscribeWayPoints
- final UnsubscribeWayPointsResponse msg = new UnsubscribeWayPointsResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onUnsubscribeWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onUnsubscribeWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_WAY_POINTS.toString())) {
- // GetWayPoints
- final GetWayPointsResponse msg = new GetWayPointsResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetWayPointsResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.READ_DID.toString())) {
- final ReadDIDResponse msg = new ReadDIDResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onReadDIDResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onReadDIDResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_DTCS.toString())) {
- final GetDTCsResponse msg = new GetDTCsResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetDTCsResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetDTCsResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.DIAGNOSTIC_MESSAGE.toString())) {
- final DiagnosticMessageResponse msg = new DiagnosticMessageResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDiagnosticMessageResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDiagnosticMessageResponse(msg);
- onRPCResponseReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.SYSTEM_REQUEST.toString())) {
-
- final SystemRequestResponse msg = new SystemRequestResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSystemRequestResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSystemRequestResponse(msg);
- onRPCResponseReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.SEND_LOCATION.toString())) {
-
- final SendLocationResponse msg = new SendLocationResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSendLocationResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSendLocationResponse(msg);
- onRPCResponseReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.DIAL_NUMBER.toString())) {
-
- final DialNumberResponse msg = new DialNumberResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onDialNumberResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onDialNumberResponse(msg);
- onRPCResponseReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.SHOW_CONSTANT_TBT.toString())) {
- final ShowConstantTbtResponse msg = new ShowConstantTbtResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onShowConstantTbtResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onShowConstantTbtResponse(msg);
- onRPCResponseReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ALERT_MANEUVER.toString())) {
- final AlertManeuverResponse msg = new AlertManeuverResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onAlertManeuverResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onAlertManeuverResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UPDATE_TURN_LIST.toString())) {
- final UpdateTurnListResponse msg = new UpdateTurnListResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onUpdateTurnListResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onUpdateTurnListResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_INTERIOR_VEHICLE_DATA.toString())) {
- final SetInteriorVehicleDataResponse msg = new SetInteriorVehicleDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetInteriorVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetInteriorVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_INTERIOR_VEHICLE_DATA.toString())) {
- final GetInteriorVehicleDataResponse msg = new GetInteriorVehicleDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetInteriorVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetInteriorVehicleDataResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_SYSTEM_CAPABILITY.toString())) {
- // GetSystemCapabilityResponse
- final GetSystemCapabilityResponse msg = new GetSystemCapabilityResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetSystemCapabilityResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetSystemCapabilityResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.BUTTON_PRESS.toString())) {
- final ButtonPressResponse msg = new ButtonPressResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onButtonPressResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onButtonPressResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SEND_HAPTIC_DATA.toString())) {
- final SendHapticDataResponse msg = new SendHapticDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSendHapticDataResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSendHapticDataResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.SET_CLOUD_APP_PROPERTIES.toString())) {
- final SetCloudAppPropertiesResponse msg = new SetCloudAppPropertiesResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onSetCloudAppProperties(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onSetCloudAppProperties(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_CLOUD_APP_PROPERTIES.toString())) {
- final GetCloudAppPropertiesResponse msg = new GetCloudAppPropertiesResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetCloudAppProperties(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetCloudAppProperties(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.PUBLISH_APP_SERVICE.toString())) {
- final PublishAppServiceResponse msg = new PublishAppServiceResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onPublishAppServiceResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onPublishAppServiceResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_APP_SERVICE_DATA.toString())) {
- final GetAppServiceDataResponse msg = new GetAppServiceDataResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetAppServiceDataResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetAppServiceDataResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.GET_FILE.toString())) {
- final GetFileResponse msg = new GetFileResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onGetFileResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onGetFileResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.PERFORM_APP_SERVICES_INTERACTION.toString())) {
- final PerformAppServiceInteractionResponse msg = new PerformAppServiceInteractionResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onPerformAppServiceInteractionResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onPerformAppServiceInteractionResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.CLOSE_APPLICATION.toString())) {
- final CloseApplicationResponse msg = new CloseApplicationResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onCloseApplicationResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onCloseApplicationResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if(functionName.equals(FunctionID.CANCEL_INTERACTION.toString())) {
- final CancelInteractionResponse msg = new CancelInteractionResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onCancelInteractionResponse(msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onCancelInteractionResponse(msg);
- onRPCResponseReceived(msg);
- }
- } else if (functionName.equals(FunctionID.UNPUBLISH_APP_SERVICE.toString())) {
- final UnpublishAppServiceResponse msg = new UnpublishAppServiceResponse(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onUnpublishAppServiceResponse( msg);
- onRPCResponseReceived(msg);
- }
- });
- } else {
- _proxyListener.onUnpublishAppServiceResponse( msg);
- onRPCResponseReceived(msg);
- }
- } else {
- if (_sdlMsgVersion != null) {
- DebugTool.logError("Unrecognized response Message: " + functionName +
- " SDL Message Version = " + _sdlMsgVersion);
- } else {
- DebugTool.logError("Unrecognized response Message: " + functionName);
- }
- } // end-if
-
- } else if (messageType.equals(RPCMessage.KEY_NOTIFICATION)) {
- if (functionName.equals(FunctionID.ON_HMI_STATUS.toString())) {
- // OnHMIStatus
-
- final OnHMIStatus msg = new OnHMIStatus(hash);
-
- //setup lockscreeninfo
- if (sdlSession != null)
- {
- sdlSession.getLockScreenMan().setHMILevel(msg.getHmiLevel());
- }
-
- msg.setFirstRun(firstTimeFull);
- if (msg.getHmiLevel() == HMILevel.HMI_FULL) firstTimeFull = false;
-
- _hmiLevel = msg.getHmiLevel();
- _audioStreamingState = msg.getAudioStreamingState();
-
- msg.format(rpcSpecVersion, true);
- lastHmiStatus = msg;
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnHMIStatus(msg);
- _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnHMIStatus(msg);
- _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_COMMAND.toString())) {
- // OnCommand
-
- final OnCommand msg = new OnCommand(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnCommand(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnCommand(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_DRIVER_DISTRACTION.toString())) {
- // OnDriverDistration
-
- final OnDriverDistraction msg = new OnDriverDistraction(hash);
-
- //setup lockscreeninfo
- if (sdlSession != null)
- {
- DriverDistractionState drDist = msg.getState();
- sdlSession.getLockScreenMan().setDriverDistStatus(drDist == DriverDistractionState.DD_ON);
- }
-
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnDriverDistraction(msg);
- _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnDriverDistraction(msg);
- _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_ENCODED_SYNC_P_DATA.toString())) {
-
- final OnSystemRequest msg = new OnSystemRequest(hash);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.ON_SYSTEM_REQUEST.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_NOTIFICATION);
-
- // If url is null, then send notification to the app, otherwise, send to URL
- if (msg.getUrl() == null) {
- updateBroadcastIntent(sendIntent, "COMMENT1", "URL is a null value (received)");
- sendBroadcastIntent(sendIntent);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnSystemRequest(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnSystemRequest(msg);
- onRPCNotificationReceived(msg);
- }
- } else {
- updateBroadcastIntent(sendIntent, "COMMENT1", "Sending to cloud: " + msg.getUrl());
- sendBroadcastIntent(sendIntent);
-
- Log.i("pt", "send to url");
-
- if ( (msg.getUrl() != null) )
- {
- Thread handleOffboardTransmissionThread = new Thread() {
- @Override
- public void run() {
- sendOnSystemRequestToUrl(msg);
- }
- };
-
- handleOffboardTransmissionThread.start();
- }
- }
- } else if (functionName.equals(FunctionID.ON_PERMISSIONS_CHANGE.toString())) {
- //OnPermissionsChange
-
- final OnPermissionsChange msg = new OnPermissionsChange(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnPermissionsChange(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnPermissionsChange(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_TBT_CLIENT_STATE.toString())) {
- // OnTBTClientState
-
- final OnTBTClientState msg = new OnTBTClientState(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnTBTClientState(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnTBTClientState(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_BUTTON_PRESS.toString())) {
- // OnButtonPress
-
- final OnButtonPress msg = new OnButtonPress(hash);
- msg.format(rpcSpecVersion, true);
- final OnButtonPress onButtonPressCompat = (OnButtonPress)handleButtonNotificationFormatting(msg);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnButtonPress(msg);
- onRPCNotificationReceived(msg);
- if(onButtonPressCompat != null){
- onRPCNotificationReceived(onButtonPressCompat);
- _proxyListener.onOnButtonPress(onButtonPressCompat);
- }
- }
- });
- } else {
- _proxyListener.onOnButtonPress(msg);
- onRPCNotificationReceived(msg);
- if(onButtonPressCompat != null){
- onRPCNotificationReceived(onButtonPressCompat);
- _proxyListener.onOnButtonPress(onButtonPressCompat);
- }
- }
- } else if (functionName.equals(FunctionID.ON_BUTTON_EVENT.toString())) {
- // OnButtonEvent
-
- final OnButtonEvent msg = new OnButtonEvent(hash);
- msg.format(rpcSpecVersion, true);
- final OnButtonEvent onButtonEventCompat = (OnButtonEvent)handleButtonNotificationFormatting(msg);
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnButtonEvent(msg);
- onRPCNotificationReceived(msg);
- if(onButtonEventCompat != null){
- onRPCNotificationReceived(onButtonEventCompat);
- _proxyListener.onOnButtonEvent(onButtonEventCompat);
- }
- }
- });
- } else {
- _proxyListener.onOnButtonEvent(msg);
- onRPCNotificationReceived(msg);
- if(onButtonEventCompat != null){
- onRPCNotificationReceived(onButtonEventCompat);
- _proxyListener.onOnButtonEvent(onButtonEventCompat);
- }
- }
- } else if (functionName.equals(FunctionID.ON_LANGUAGE_CHANGE.toString())) {
- // OnLanguageChange
-
- final OnLanguageChange msg = new OnLanguageChange(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnLanguageChange(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnLanguageChange(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_HASH_CHANGE.toString())) {
- // OnLanguageChange
-
- final OnHashChange msg = new OnHashChange(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnHashChange(msg);
- onRPCNotificationReceived(msg);
- if (_bAppResumeEnabled)
- {
- _lastHashID = msg.getHashID();
- }
- }
- });
- } else {
- _proxyListener.onOnHashChange(msg);
- onRPCNotificationReceived(msg);
- if (_bAppResumeEnabled)
- {
- _lastHashID = msg.getHashID();
- }
- }
- } else if (functionName.equals(FunctionID.ON_SYSTEM_REQUEST.toString())) {
- // OnSystemRequest
-
- final OnSystemRequest msg = new OnSystemRequest(hash);
- msg.format(rpcSpecVersion,true);
- RequestType requestType = msg.getRequestType();
- if(msg.getUrl() != null) {
- if (((requestType == RequestType.PROPRIETARY) && (msg.getFileType() == FileType.JSON))
- || ((requestType == RequestType.HTTP) && (msg.getFileType() == FileType.BINARY))) {
- Thread handleOffboardTransmissionThread = new Thread() {
- @Override
- public void run() {
- sendOnSystemRequestToUrl(msg);
- }
- };
-
- handleOffboardTransmissionThread.start();
- } else if (requestType == RequestType.LOCK_SCREEN_ICON_URL) {
- //Cache this for when the lockscreen is displayed
- lockScreenIconRequest = msg;
- } else if (requestType == RequestType.ICON_URL) {
- //Download the icon file and send SystemRequest RPC
- Thread handleOffBoardTransmissionThread = new Thread() {
- @Override
- public void run() {
- byte[] file = FileUtls.downloadFile(msg.getUrl());
- if (file != null) {
- SystemRequest systemRequest = new SystemRequest();
- systemRequest.setFileName(msg.getUrl());
- systemRequest.setBulkData(file);
- systemRequest.setRequestType(RequestType.ICON_URL);
- try {
- sendRPCMessagePrivate(systemRequest);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- } else {
- DebugTool.logError("File was null at: " + msg.getUrl());
- }
- }
- };
- handleOffBoardTransmissionThread.start();
- }
- }
-
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnSystemRequest(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnSystemRequest(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_AUDIO_PASS_THRU.toString())) {
- // OnAudioPassThru
- final OnAudioPassThru msg = new OnAudioPassThru(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnAudioPassThru(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnAudioPassThru(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_VEHICLE_DATA.toString())) {
- // OnVehicleData
- final OnVehicleData msg = new OnVehicleData(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnVehicleData(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnVehicleData(msg);
- onRPCNotificationReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ON_APP_INTERFACE_UNREGISTERED.toString())) {
- // OnAppInterfaceUnregistered
-
- _appInterfaceRegisterd = false;
- synchronized(APP_INTERFACE_REGISTERED_LOCK) {
- APP_INTERFACE_REGISTERED_LOCK.notify();
- }
-
- final OnAppInterfaceUnregistered msg = new OnAppInterfaceUnregistered(hash);
- msg.format(rpcSpecVersion,true);
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.ON_APP_INTERFACE_UNREGISTERED.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_NOTIFICATION);
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- sendBroadcastIntent(sendIntent);
-
- if (_advancedLifecycleManagementEnabled) {
- // This requires the proxy to be cycled
- cycleProxy(SdlDisconnectedReason.convertAppInterfaceUnregisteredReason(msg.getReason()));
- } else {
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg);
- onRPCNotificationReceived(msg);
- }
- notifyProxyClosed("OnAppInterfaceUnregistered", null, SdlDisconnectedReason.APP_INTERFACE_UNREG);
- }
- }
- else if (functionName.equals(FunctionID.ON_KEYBOARD_INPUT.toString())) {
- final OnKeyboardInput msg = new OnKeyboardInput(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnKeyboardInput(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnKeyboardInput(msg);
- onRPCNotificationReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ON_TOUCH_EVENT.toString())) {
- final OnTouchEvent msg = new OnTouchEvent(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnTouchEvent(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnTouchEvent(msg);
- onRPCNotificationReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ON_WAY_POINT_CHANGE.toString())) {
- final OnWayPointChange msg = new OnWayPointChange(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnWayPointChange(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnWayPointChange(msg);
- onRPCNotificationReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ON_INTERIOR_VEHICLE_DATA.toString())) {
- final OnInteriorVehicleData msg = new OnInteriorVehicleData(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnInteriorVehicleData(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnInteriorVehicleData(msg);
- onRPCNotificationReceived(msg);
- }
- }
- else if (functionName.equals(FunctionID.ON_RC_STATUS.toString())) {
- final OnRCStatus msg = new OnRCStatus(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnRCStatus(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnRCStatus(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_APP_SERVICE_DATA.toString())) {
- final OnAppServiceData msg = new OnAppServiceData(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnAppServiceData(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnAppServiceData(msg);
- onRPCNotificationReceived(msg);
- }
- } else if (functionName.equals(FunctionID.ON_SYSTEM_CAPABILITY_UPDATED.toString())) {
- final OnSystemCapabilityUpdated msg = new OnSystemCapabilityUpdated(hash);
- msg.format(rpcSpecVersion, true);
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onOnSystemCapabilityUpdated(msg);
- onRPCNotificationReceived(msg);
- }
- });
- } else {
- _proxyListener.onOnSystemCapabilityUpdated(msg);
- onRPCNotificationReceived(msg);
- }
- } else {
- if (_sdlMsgVersion != null) {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName +
- " connected to SDL using message version: " + _sdlMsgVersion.getMajorVersion() + "." + _sdlMsgVersion.getMinorVersion());
- } else {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName);
- }
- } // end-if
- } // end-if notification
-
- SdlTrace.logProxyEvent("Proxy received RPC Message: " + functionName, SDL_LIB_TRACE_KEY);
- }
-
- //FIXME
- /**
- * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old
- * OK button name. This should be removed during the next major release
- * @param notification
- */
- private RPCNotification handleButtonNotificationFormatting(RPCNotification notification){
- if(FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName())
- || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())){
-
- ButtonName buttonName = (ButtonName)notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME);
- ButtonName compatBtnName = null;
-
- if(rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5){
- if(ButtonName.PLAY_PAUSE.equals(buttonName)){
- compatBtnName = ButtonName.OK;
- }
- }else{ // rpc spec version is either null or less than 5
- if(ButtonName.OK.equals(buttonName)){
- compatBtnName = ButtonName.PLAY_PAUSE;
- }
- }
-
- try {
- if (compatBtnName != null) { //There is a button name that needs to be swapped out
- RPCNotification notification2;
- //The following is done because there is currently no way to make a deep copy
- //of an RPC. Since this code will be removed, it's ugliness is borderline acceptable.
- if (notification instanceof OnButtonEvent) {
- OnButtonEvent onButtonEvent = new OnButtonEvent();
- onButtonEvent.setButtonEventMode(((OnButtonEvent) notification).getButtonEventMode());
- onButtonEvent.setCustomButtonID(((OnButtonEvent) notification).getCustomButtonID());
- notification2 = onButtonEvent;
- } else if (notification instanceof OnButtonPress) {
- OnButtonPress onButtonPress = new OnButtonPress();
- onButtonPress.setButtonPressMode(((OnButtonPress) notification).getButtonPressMode());
- onButtonPress.setCustomButtonName(((OnButtonPress) notification).getCustomButtonName());
- notification2 = onButtonPress;
- } else {
- return null;
- }
-
- notification2.setParameters(OnButtonEvent.KEY_BUTTON_NAME, compatBtnName);
- return notification2;
- }
- }catch (Exception e){
- //Should never get here
- }
- }
- return null;
- }
-
- /**
- * Get SDL Message Version
- * @return SdlMsgVersion
- * @throws SdlException
- */
- public SdlMsgVersion getSdlMsgVersion() throws SdlException{
- return _sdlMsgVersion;
- }
-
- /**
- * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener.
- * For sending requests asynchronously, use sendRequests <br>
- *
- * <strong>NOTE: This will override any listeners on individual RPCs</strong>
- *
- * @param rpcs is the list of RPCMessages being sent
- * @param listener listener for updates and completions
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void sendSequentialRequests(final List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) throws SdlException {
- if (_proxyDisposed) {
- throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
- }
-
- SdlTrace.logProxyEvent("Application called sendSequentialRequests", SDL_LIB_TRACE_KEY);
-
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (!getIsConnected()) {
- SdlTrace.logProxyEvent("Application attempted to call sendSequentialRequests without a connected transport.", SDL_LIB_TRACE_KEY);
- throw new SdlException("There is no valid connection to SDL. sendSequentialRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
- }
- }
-
- if (rpcs == null){
- //Log error here
- throw new SdlException("You must send some RPCs", SdlExceptionCause.INVALID_ARGUMENT);
- }
-
- // Break out of recursion, we have finished the requests
- if (rpcs.size() == 0) {
- if(listener != null){
- listener.onFinished();
- }
- return;
- }
-
- RPCMessage rpc = rpcs.remove(0);
-
- // Request Specifics
- if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) {
- RPCRequest request = (RPCRequest) rpc;
- request.setCorrelationID(CorrelationIdGenerator.generateId());
-
- final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener();
-
- request.setOnRPCResponseListener(new OnRPCResponseListener() {
- @Override
- public void onResponse(int correlationId, RPCResponse response) {
- if (devOnRPCResponseListener != null){
- devOnRPCResponseListener.onResponse(correlationId, response);
- }
- if (listener != null) {
- listener.onResponse(correlationId, response);
- listener.onUpdate(rpcs.size());
-
- }
- try {
- // recurse after onResponse
- sendSequentialRequests(rpcs, listener);
- } catch (SdlException e) {
- e.printStackTrace();
- if (listener != null) {
- listener.onError(correlationId, Result.GENERIC_ERROR, e.toString());
- }
- }
- }
-
- @Override
- public void onError(int correlationId, Result resultCode, String info) {
- if (devOnRPCResponseListener != null){
- devOnRPCResponseListener.onError(correlationId, resultCode, info);
- }
- if (listener != null) {
- listener.onError(correlationId, resultCode, info);
- listener.onUpdate(rpcs.size());
- }
- try {
- // recurse after onError
- sendSequentialRequests(rpcs, listener);
- } catch (SdlException e) {
- e.printStackTrace();
- if (listener != null) {
- listener.onError(correlationId, Result.GENERIC_ERROR, e.toString());
- }
- }
- }
- });
- sendRPCMessagePrivate(request);
- } else {
- // Notifications and Responses
- sendRPCMessagePrivate(rpc);
- if (listener != null) {
- listener.onUpdate(rpcs.size());
- }
- // recurse after sending a notification or response as there is no response.
- try {
- sendSequentialRequests(rpcs, listener);
- } catch (SdlException e) {
- e.printStackTrace();
- if (listener != null) {
- listener.onError(0, Result.GENERIC_ERROR, e.toString());
- }
- }
- }
-
-
- }
-
- /**
- * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener.
- * For sending requests synchronously, use sendSequentialRequests <br>
- *
- * <strong>NOTE: This will override any listeners on individual RPCs</strong>
- *
- * @param rpcs is the list of RPCMessages being sent
- * @param listener listener for updates and completions
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void sendRequests(List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) throws SdlException {
-
- if (_proxyDisposed) {
- throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
- }
-
- SdlTrace.logProxyEvent("Application called sendRequests", SDL_LIB_TRACE_KEY);
-
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (!getIsConnected()) {
- SdlTrace.logProxyEvent("Application attempted to call sendRequests without a connected transport.", SDL_LIB_TRACE_KEY);
- throw new SdlException("There is no valid connection to SDL. sendRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
- }
- }
-
- if (rpcs == null){
- //Log error here
- throw new SdlException("You must send some RPCs, the array is null", SdlExceptionCause.INVALID_ARGUMENT);
- }
-
- int arraySize = rpcs.size();
-
- if (arraySize == 0) {
- throw new SdlException("You must send some RPCs, the array is empty", SdlExceptionCause.INVALID_ARGUMENT);
- }
-
- for (int i = 0; i < arraySize; i++) {
- RPCMessage rpc = rpcs.get(i);
- // Request Specifics
- if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) {
- RPCRequest request = (RPCRequest) rpc;
- final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener();
- request.setCorrelationID(CorrelationIdGenerator.generateId());
- if (listener != null) {
- listener.addCorrelationId(request.getCorrelationID());
- request.setOnRPCResponseListener(new OnRPCResponseListener() {
- @Override
- public void onResponse(int correlationId, RPCResponse response) {
- if (devOnRPCResponseListener != null){
- devOnRPCResponseListener.onResponse(correlationId, response);
- }
- if (listener.getSingleRpcResponseListener() != null) {
- listener.getSingleRpcResponseListener().onResponse(correlationId, response);
- }
- }
-
- @Override
- public void onError(int correlationId, Result resultCode, String info) {
- super.onError(correlationId, resultCode, info);
- if (devOnRPCResponseListener != null){
- devOnRPCResponseListener.onError(correlationId, resultCode, info);
- }
- if (listener.getSingleRpcResponseListener() != null) {
- listener.getSingleRpcResponseListener().onError(correlationId, resultCode, info);
- }
- }
- });
- }
- sendRPCMessagePrivate(request);
- }else {
- // Notifications and Responses
- sendRPCMessagePrivate(rpc);
- if (listener != null){
- listener.onUpdate(rpcs.size());
- if (rpcs.size() == 0){
- listener.onFinished();
- }
- }
- }
- }
- }
-
- public void sendRPC(RPCMessage message) throws SdlException {
- if (_proxyDisposed) {
- throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
- }
-
- // Test if request is null
- if (message == null) {
- SdlTrace.logProxyEvent("Application called sendRPCRequest method with a null RPCRequest.", SDL_LIB_TRACE_KEY);
- throw new IllegalArgumentException("sendRPCRequest cannot be called with a null request.");
- }
-
- SdlTrace.logProxyEvent("Application called sendRPCRequest method for RPCRequest: ." + message.getFunctionName(), SDL_LIB_TRACE_KEY);
-
- // Test if SdlConnection is null
- synchronized(CONNECTION_REFERENCE_LOCK) {
- if (!getIsConnected()) {
- SdlTrace.logProxyEvent("Application attempted to send and RPCRequest without a connected transport.", SDL_LIB_TRACE_KEY);
- throw new SdlException("There is no valid connection to SDL. sendRPCRequest cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
- }
- }
-
- // Test for illegal correlation ID
- if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) {
- RPCRequest request = (RPCRequest) message;
- if (isCorrelationIDProtected(request.getCorrelationID())) {
-
- SdlTrace.logProxyEvent("Application attempted to use the reserved correlation ID, " + request.getCorrelationID(), SDL_LIB_TRACE_KEY);
- throw new SdlException("Invalid correlation ID. The correlation ID, " + request.getCorrelationID()
- + " , is a reserved correlation ID.", SdlExceptionCause.RESERVED_CORRELATION_ID);
- }
- }
- // Throw exception if RPCRequest is sent when SDL is unavailable
- if (!_appInterfaceRegisterd && !message.getFunctionName().equals(FunctionID.REGISTER_APP_INTERFACE.toString())) {
-
- SdlTrace.logProxyEvent("Application attempted to send an RPCRequest (non-registerAppInterface), before the interface was registerd.", SDL_LIB_TRACE_KEY);
- throw new SdlException("SDL is currently unavailable. RPC Requests cannot be sent.", SdlExceptionCause.SDL_UNAVAILABLE);
- }
-
- if (_advancedLifecycleManagementEnabled) {
- if (message.getFunctionName().equals(FunctionID.REGISTER_APP_INTERFACE.toString())
- || message.getFunctionName().equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) {
-
- SdlTrace.logProxyEvent("Application attempted to send a RegisterAppInterface or UnregisterAppInterface while using ALM.", SDL_LIB_TRACE_KEY);
- throw new SdlException("The RPCRequest, " + message.getFunctionName() +
- ", is un-allowed using the Advanced Lifecycle Management Model.", SdlExceptionCause.INCORRECT_LIFECYCLE_MODEL);
- }
- }
-
- sendRPCMessagePrivate(message);
- }
-
- /**
- * Takes an RPCRequest and sends it to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param request is the RPCRequest being sent
- * @throws SdlException if an unrecoverable error is encountered
- * @deprecated - use sendRPC instead
- */
- @Deprecated
- public void sendRPCRequest(RPCRequest request) throws SdlException {
- sendRPC(request);
- }
-
- protected void notifyProxyClosed(final String info, final Exception e, final SdlDisconnectedReason reason) {
- SdlTrace.logProxyEvent("NotifyProxyClose", SDL_LIB_TRACE_KEY);
- Log.d(TAG, "notifyProxyClosed: " + info);
- OnProxyClosed message = new OnProxyClosed(info, e, reason);
- queueInternalMessage(message);
- }
-
- private void passErrorToProxyListener(final String info, final Exception e) {
-
- OnError message = new OnError(info, e);
- queueInternalMessage(message);
- }
-
- private void startRPCProtocolSession() {
-
- // Set Proxy Lifecyclek Available
- if (_advancedLifecycleManagementEnabled) {
-
- try {
- registerAppInterfacePrivate(
- _sdlMsgVersionRequest,
- _applicationName,
- _ttsName,
- _ngnMediaScreenAppName,
- _vrSynonyms,
- _isMediaApp,
- _sdlLanguageDesired,
- _hmiDisplayLanguageDesired,
- _appType,
- _appID,
- _dayColorScheme,
- _nightColorScheme,
- REGISTER_APP_INTERFACE_CORRELATION_ID);
-
- } catch (Exception e) {
- notifyProxyClosed("Failed to register application interface with SDL. Check parameter values given to SdlProxy constructor.", e, SdlDisconnectedReason.SDL_REGISTRATION_ERROR);
- }
- } else {
- InternalProxyMessage message = new InternalProxyMessage(InternalProxyMessage.OnProxyOpened);
- queueInternalMessage(message);
- }
- }
-
- // Queue internal callback message
- private void queueInternalMessage(InternalProxyMessage message) {
- synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_internalProxyMessageDispatcher != null) {
- _internalProxyMessageDispatcher.queueMessage(message);
- }
- }
- }
-
- // Queue incoming ProtocolMessage
- private void queueIncomingMessage(ProtocolMessage message) {
- synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) {
- if (_incomingProxyMessageDispatcher != null) {
- _incomingProxyMessageDispatcher.queueMessage(message);
- }
- }
- }
-
- private FileInputStream getFileInputStream(String sLocalFile)
- {
- FileInputStream is = null;
- try
- {
- is = new FileInputStream(sLocalFile);
- }
- catch (IOException e1)
- {
- e1.printStackTrace();
- }
- return is;
- }
-
- private Long getFileInputStreamSize(FileInputStream is)
- {
- Long lSize = null;
-
- try
- {
- lSize = is.getChannel().size();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return lSize;
- }
-
- private void closeFileInputStream(FileInputStream is)
- {
- try
- {
- is.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- @SuppressWarnings("unchecked")
- private RPCStreamController startRPCStream(String sLocalFile, PutFile request, SessionType sType, byte rpcSessionID, Version protocolVersion)
- {
- if (sdlSession == null) return null;
-
- FileInputStream is = getFileInputStream(sLocalFile);
- if (is == null) return null;
-
- Long lSize = getFileInputStreamSize(is);
- if (lSize == null)
- {
- closeFileInputStream(is);
- return null;
- }
-
- try {
- StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, protocolVersion, rpcSpecVersion, lSize, sdlSession);
- rpcPacketizer.start();
- return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
- } catch (Exception e) {
- Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
- return null;
- }
- }
-
- @SuppressWarnings({"unchecked", "UnusedReturnValue"})
- private RPCStreamController startRPCStream(InputStream is, PutFile request, SessionType sType, byte rpcSessionID, Version protocolVersion)
- {
- if (sdlSession == null) return null;
- Long lSize = request.getLength();
-
- if (lSize == null)
- {
- return null;
- }
-
- try {
- StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, protocolVersion, rpcSpecVersion, lSize, sdlSession);
- rpcPacketizer.start();
- return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
- } catch (Exception e) {
- Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
- return null;
- }
- }
-
- private RPCStreamController startPutFileStream(String sPath, PutFile msg) {
- if (sdlSession == null) return null;
- return startRPCStream(sPath, msg, SessionType.RPC, sdlSession.getSessionId(), protocolVersion);
- }
-
- private RPCStreamController startPutFileStream(InputStream is, PutFile msg) {
- if (sdlSession == null) return null;
- if (is == null) return null;
- return startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), protocolVersion);
- }
-
- @SuppressWarnings("UnusedReturnValue")
- public boolean startRPCStream(InputStream is, RPCRequest msg) {
- if (sdlSession == null) return false;
- sdlSession.startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), (byte)getProtocolVersion().getMajor());
- return true;
- }
-
- public OutputStream startRPCStream(RPCRequest msg) {
- if (sdlSession == null) return null;
- return sdlSession.startRPCStream(msg, SessionType.RPC, sdlSession.getSessionId(), (byte)getProtocolVersion().getMajor());
- }
-
- public void endRPCStream() {
- if (sdlSession == null) return;
- sdlSession.stopRPCStream();
- }
-
- private class CallableMethod implements Callable<Void> {
-
- private final long waitTime;
-
- public CallableMethod(int timeInMillis){
- this.waitTime=timeInMillis;
- }
- @Override
- public Void call() {
- try {
- Thread.sleep(waitTime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
-
- public FutureTask<Void> createFutureTask(CallableMethod callMethod){
- return new FutureTask<Void>(callMethod);
- }
-
- public ScheduledExecutorService createScheduler(){
- return Executors.newSingleThreadScheduledExecutor();
- }
-
- @SuppressWarnings("unused")
- public void startService(SessionType serviceType, boolean isEncrypted){
- sdlSession.startService(serviceType, sdlSession.getSessionId(), isEncrypted);
- }
-
- @SuppressWarnings("unused")
- public void endService(SessionType serviceType){
- sdlSession.endService(serviceType, sdlSession.getSessionId());
- }
-
-
-
- /**
- * @deprecated
- *Opens the video service (serviceType 11) and subsequently streams raw H264 video from an InputStream provided by the app
- *@return true if service is opened successfully and stream is started, return false otherwise
- * @see #startRemoteDisplayStream(Context, Class, VideoStreamingParameters, boolean) startRemoteDisplayStream
- * @see #startVideoStream(boolean, VideoStreamingParameters) startVideoStream
- * @see #createOpenGLInputSurface(int, int, int, int, int, boolean) createOpenGLInputSurface
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean startH264(InputStream is, boolean isEncrypted) {
-
- if (sdlSession == null) return false;
-
- navServiceStartResponseReceived = false;
- navServiceStartResponse = false;
- navServiceStartRejectedParams = null;
-
- // When startH264() API is used, we will not send video format / width / height information
- // with StartService. (Reasons: InputStream does not provide timestamp information so RTP
- // cannot be used. startH264() does not provide with/height information.)
- VideoStreamingParameters emptyParam = new VideoStreamingParameters();
- emptyParam.setResolution(null);
- emptyParam.setFormat(null);
- sdlSession.setDesiredVideoParams(emptyParam);
-
- sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!navServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- if (navServiceStartResponse) {
- try {
- sdlSession.startStream(is, SessionType.NAV, sdlSession.getSessionId());
- return true;
- } catch (Exception e) {
- return false;
- }
- } else {
- return false;
- }
- }
-
- /**
- * @deprecated
- *Opens the video service (serviceType 11) and subsequently provides an OutputStream to the app to use for a raw H264 video stream
- *@return OutputStream if service is opened successfully and stream is started, return null otherwise
- * @see #startRemoteDisplayStream(Context, Class, VideoStreamingParameters, boolean) startRemoteDisplayStream
- * @see #startVideoStream(boolean, VideoStreamingParameters) startVideoStream
- * @see #createOpenGLInputSurface(int, int, int, int, int, boolean) createOpenGLInputSurface
- */
- @SuppressWarnings("unused")
- @Deprecated
- public OutputStream startH264(boolean isEncrypted) {
-
- if (sdlSession == null) return null;
-
- navServiceStartResponseReceived = false;
- navServiceStartResponse = false;
- navServiceStartRejectedParams = null;
-
- // When startH264() API is used, we will not send video format / width / height information
- // with StartService. (Reasons: OutputStream does not provide timestamp information so RTP
- // cannot be used. startH264() does not provide with/height information.)
- VideoStreamingParameters emptyParam = new VideoStreamingParameters();
- emptyParam.setResolution(null);
- emptyParam.setFormat(null);
- sdlSession.setDesiredVideoParams(emptyParam);
-
- sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!navServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- if (navServiceStartResponse) {
- try {
- return sdlSession.startStream(SessionType.NAV, sdlSession.getSessionId());
- } catch (Exception e) {
- return null;
- }
- } else {
- return null;
- }
- }
-
- /**
- *Closes the opened video service (serviceType 11)
- *@return true if the video service is closed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean endH264() {
- return endVideoStream();
- }
- /**
- *Pauses the stream for the opened audio service (serviceType 10)
- *@return true if the audio service stream is paused successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean pausePCM() {
- return pauseAudioStream();
- }
-
- /**
- *Pauses the stream for the opened video service (serviceType 11)
- *@return true if the video service stream is paused successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean pauseH264() {
- return pauseVideoStream();
- }
-
- /**
- *Resumes the stream for the opened audio service (serviceType 10)
- *@return true if the audio service stream is resumed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean resumePCM() {
- return resumeAudioStream();
- }
-
- /**
- *Resumes the stream for the opened video service (serviceType 11)
- *@return true if the video service is resumed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean resumeH264() {
- return resumeVideoStream();
- }
-
-
- /**
- *Opens the audio service (serviceType 10) and subsequently streams raw PCM audio from an InputStream provided by the app
- *@return true if service is opened successfully and stream is started, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean startPCM(InputStream is, boolean isEncrypted) {
- if (sdlSession == null) return false;
-
- pcmServiceStartResponseReceived = false;
- pcmServiceStartResponse = false;
- sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!pcmServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- if (pcmServiceStartResponse) {
- try {
- sdlSession.startStream(is, SessionType.PCM, sdlSession.getSessionId());
- return true;
- } catch (Exception e) {
- return false;
- }
- } else {
- return false;
- }
- }
-
- /**
- *Opens the audio service (serviceType 10) and subsequently provides an OutputStream to the app
- *@return OutputStream if service is opened successfully and stream is started, return null otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public OutputStream startPCM(boolean isEncrypted) {
- if (sdlSession == null) return null;
-
- pcmServiceStartResponseReceived = false;
- pcmServiceStartResponse = false;
- sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!pcmServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- if (pcmServiceStartResponse) {
- try {
- return sdlSession.startStream(SessionType.PCM, sdlSession.getSessionId());
- } catch (Exception e) {
- return null;
- }
- } else {
- if (pcmServiceStartRejectedParams != null) {
- StringBuilder builder = new StringBuilder();
- for (String paramName : pcmServiceStartRejectedParams) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append(paramName);
- }
- DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
-
- } else {
- DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
- }
- return null;
- }
- }
-
- /**
- *Closes the opened audio service (serviceType 10)
- *@return true if the audio service is closed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- @Deprecated
- public boolean endPCM() {
- return endAudioStream();
- }
-
- /**
- * Opens a video service (service type 11) and subsequently provides an IVideoStreamListener
- * to the app to send video data. The supplied VideoStreamingParameters will be set as desired parameters
- * that will be used to negotiate
- *
- * <br><br><b>NOTE: IF USING SECONDARY TRANSPORTS, THE VIDEO SERVICE MUST BE STARTED BEFORE CALLING THIS
- * THIS METHOD. USE A `ISdlServiceListener` TO BE NOTIFIED THAT IT STARTS THEN CALL THIS METHOD TO
- * START STREAMING. ADD A LISTENER USE {@link #addServiceListener(SessionType, ISdlServiceListener)}.</b>
- *
- * @param isEncrypted Specify true if packets on this service have to be encrypted
- * @param parameters Video streaming parameters including: codec which will be used for streaming (currently, only
- * VideoStreamingCodec.H264 is accepted), height and width of the video in pixels.
- *
- * @return IVideoStreamListener interface if service is opened successfully and streaming is
- * started, null otherwise
- *
- * @see ISdlServiceListener
- */
- @SuppressWarnings("unused")
- public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
- if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
- return null;
- }
- if (!sdlSession.getIsConnected()) {
- DebugTool.logWarning("Connection is not available.");
- return null;
- }
-
- sdlSession.setDesiredVideoParams(parameters);
-
- VideoStreamingParameters acceptedParams = tryStartVideoStream(isEncrypted, parameters);
- if (acceptedParams != null) {
- return sdlSession.startVideoStream();
- } else {
- return null;
- }
- }
-
- /**
- *Closes the opened video service (serviceType 11)
- *@return true if the video service is closed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean endVideoStream() {
- if (sdlSession == null){ return false; }
-
- navServiceEndResponseReceived = false;
- navServiceEndResponse = false;
- sdlSession.stopVideoStream();
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!navServiceEndResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- return navServiceEndResponse;
- }
-
- /**
- *Pauses the stream for the opened video service (serviceType 11)
- *@return true if the video service stream is paused successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean pauseVideoStream() {
- return sdlSession != null && sdlSession.pauseVideoStream();
- }
-
- /**
- *Resumes the stream for the opened video service (serviceType 11)
- *@return true if the video service is resumed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean resumeVideoStream() {
- return sdlSession != null && sdlSession.resumeVideoStream();
- }
-
- /**
- * Opens the video service (serviceType 11) and creates a Surface (used for streaming video) with input parameters provided by the app
- * @param frameRate - specified rate of frames to utilize for creation of Surface
- * @param iFrameInterval - specified interval to utilize for creation of Surface
- * @param width - specified width to utilize for creation of Surface
- * @param height - specified height to utilize for creation of Surface
- * @param bitrate - specified bitrate to utilize for creation of Surface
- *@return Surface if service is opened successfully and stream is started, return null otherwise
- */
- @SuppressWarnings("unused")
- public Surface createOpenGLInputSurface(int frameRate, int iFrameInterval, int width,
- int height, int bitrate, boolean isEncrypted) {
-
- if (sdlSession == null || !sdlSession.getIsConnected()){
- return null;
- }
-
- VideoStreamingParameters desired = new VideoStreamingParameters();
- desired.setFrameRate(frameRate);
- desired.setInterval(iFrameInterval);
- ImageResolution resolution = new ImageResolution();
- resolution.setResolutionWidth(width);
- resolution.setResolutionHeight(height);
- desired.setResolution(resolution);
- desired.setBitrate(bitrate);
-
- VideoStreamingParameters acceptedParams = tryStartVideoStream(isEncrypted, desired);
- if (acceptedParams != null) {
- return sdlSession.createOpenGLInputSurface(frameRate, iFrameInterval, width,
- height, bitrate, SessionType.NAV, sdlSession.getSessionId());
- } else {
- return null;
- }
- }
-
- /**
- * Starts streaming a remote display to the module if there is a connected session. This method of streaming requires the device to be on API level 19 or higher
- * @param context a context that can be used to create the remote display
- * @param remoteDisplay class object of the remote display. This class will be used to create an instance of the remote display and will be projected to the module
- * @param parameters streaming parameters to be used when streaming. If null is sent in, the default/optimized options will be used.
- * If you are unsure about what parameters to be used it is best to just send null and let the system determine what
- * works best for the currently connected module.
- *
- * @param encrypted a flag of if the stream should be encrypted. Only set if you have a supplied encryption library that the module can understand.
- */
- @TargetApi(19)
- public void startRemoteDisplayStream(Context context, final Class<? extends SdlRemoteDisplay> remoteDisplay, final VideoStreamingParameters parameters, final boolean encrypted){
- if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){
- Log.e(TAG, "Video streaming not supported on this module");
- return;
- }
- //Create streaming manager
- if(manager == null){
- manager = new VideoStreamingManager(context,this._internalInterface);
- }
-
- if(parameters == null){
- if(protocolVersion!= null && protocolVersion.getMajor() >= 5) {
- _systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING, new OnSystemCapabilityListener() {
- @Override
- public void onCapabilityRetrieved(Object capability) {
- VideoStreamingParameters params = new VideoStreamingParameters();
- params.update((VideoStreamingCapability)capability); //Streaming parameters are ready time to stream
- sdlSession.setDesiredVideoParams(params);
- manager.startVideoStreaming(remoteDisplay, params, encrypted);
- }
-
- @Override
- public void onError(String info) {
- Log.e(TAG, "Error retrieving video streaming capability: " + info);
-
- }
- });
- }else{
- //We just use default video streaming params
- VideoStreamingParameters params = new VideoStreamingParameters();
- DisplayCapabilities dispCap = (DisplayCapabilities)_systemCapabilityManager.getCapability(SystemCapabilityType.DISPLAY);
- if(dispCap !=null){
- params.setResolution(dispCap.getScreenParams().getImageResolution());
- }
- sdlSession.setDesiredVideoParams(params);
- manager.startVideoStreaming(remoteDisplay,params, encrypted);
- }
- }else{
- sdlSession.setDesiredVideoParams(parameters);
- manager.startVideoStreaming(remoteDisplay,parameters, encrypted);
- }
- }
-
- /**
- * Stops the remote display stream if one has been started
- */
- public void stopRemoteDisplayStream(){
- if(manager!=null){
- manager.dispose();
- }
- manager = null;
- }
-
- /**
- * Try to open a video service by using the video streaming parameters supplied.
- *
- * Only information from codecs, width and height are used during video format negotiation.
- *
- * @param isEncrypted Specify true if packets on this service have to be encrypted
- * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted.
- *
- * @return If the service is opened successfully, an instance of VideoStreamingParams is
- * returned which contains accepted video format. If the service is opened with legacy
- * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is
- * returned. If the service was not opened then null is returned.
- */
- @SuppressWarnings("unused")
- private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
- if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
- return null;
- }
- if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){
- DebugTool.logWarning("Module doesn't support video streaming.");
- return null;
- }
- if (parameters == null) {
- DebugTool.logWarning("Video parameters were not supplied.");
- return null;
- }
-
- if(!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before
- || (navServiceStartResponse && isEncrypted && !sdlSession.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one
- sdlSession.setDesiredVideoParams(parameters);
-
- navServiceStartResponseReceived = false;
- navServiceStartResponse = false;
- navServiceStartRejectedParams = null;
-
- sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!navServiceStartResponseReceived && !fTask.isDone()) ;
- scheduler.shutdown();
- }
-
- if (navServiceStartResponse) {
- if(protocolVersion!= null && protocolVersion.getMajor() < 5){ //Versions 1-4 do not support streaming parameter negotiations
- sdlSession.setAcceptedVideoParams(parameters);
- }
- return sdlSession.getAcceptedVideoParams();
- }
-
- if (navServiceStartRejectedParams != null) {
- StringBuilder builder = new StringBuilder();
- for (String paramName : navServiceStartRejectedParams) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append(paramName);
- }
-
- DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
-
- } else {
- DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
- }
-
- return null;
- }
-
- /**
- *Starts the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
- */
- @SuppressWarnings("unused")
- public void startEncoder () {
- if (sdlSession == null || !sdlSession.getIsConnected()) return;
-
- sdlSession.startEncoder();
- }
-
- /**
- *Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
- */
- @SuppressWarnings("unused")
- public void releaseEncoder() {
- if (sdlSession == null || !sdlSession.getIsConnected()) return;
-
- sdlSession.releaseEncoder();
- }
-
- /**
- *Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
- */
- @SuppressWarnings("unused")
- public void drainEncoder(boolean endOfStream) {
- if (sdlSession == null || !sdlSession.getIsConnected()) return;
-
- sdlSession.drainEncoder(endOfStream);
- }
-
- /**
- * Opens a audio service (service type 10) and subsequently provides an IAudioStreamListener
- * to the app to send audio data.
- *
- * Currently information passed by "params" are ignored, since Audio Streaming feature lacks
- * capability negotiation mechanism. App should configure audio stream data to align with
- * head unit's capability by checking (upcoming) pcmCapabilities. The default format is in
- * 16kHz and 16 bits.
- *
- * @param isEncrypted Specify true if packets on this service have to be encrypted
- * @param codec Audio codec which will be used for streaming. Currently, only
- * AudioStreamingCodec.LPCM is accepted.
- * @param params (Reserved for future use) Additional configuration information for each
- * codec. If "codec" is AudioStreamingCodec.LPCM, "params" must be an
- * instance of LPCMParams class.
- *
- * @return IAudioStreamListener interface if service is opened successfully and streaming is
- * started, null otherwise
- */
- @SuppressWarnings("unused")
- public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec,
- AudioStreamingParams params) {
- if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
- return null;
- }
- if (!sdlSession.getIsConnected()) {
- DebugTool.logWarning("Connection is not available.");
- return null;
- }
- if (codec != AudioStreamingCodec.LPCM) {
- DebugTool.logWarning("Audio codec " + codec + " is not supported.");
- return null;
- }
-
- pcmServiceStartResponseReceived = false;
- pcmServiceStartResponse = false;
- sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!pcmServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- if (pcmServiceStartResponse) {
- DebugTool.logInfo("StartService for audio succeeded");
- return sdlSession.startAudioStream();
- } else {
- if (pcmServiceStartRejectedParams != null) {
- StringBuilder builder = new StringBuilder();
- for (String paramName : pcmServiceStartRejectedParams) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append(paramName);
- }
- DebugTool.logWarning("StartService for audio failed. Rejected params: " + builder.toString());
- } else {
- DebugTool.logWarning("StartService for audio failed (rejected params not supplied)");
- }
- return null;
- }
- }
-
- /**
- *Closes the opened audio service (serviceType 10)
- *@return true if the audio service is closed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean endAudioStream() {
- if (sdlSession == null || !sdlSession.getIsConnected()) return false;
-
- pcmServiceEndResponseReceived = false;
- pcmServiceEndResponse = false;
- sdlSession.stopAudioStream();
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!pcmServiceEndResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- return pcmServiceEndResponse;
- }
-
- /**
- *Pauses the stream for the opened audio service (serviceType 10)
- *@return true if the audio service stream is paused successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean pauseAudioStream() {
- return sdlSession != null && sdlSession.pauseAudioStream();
- }
-
- /**
- *Resumes the stream for the opened audio service (serviceType 10)
- *@return true if the audio service stream is resumed successfully, return false otherwise
- */
- @SuppressWarnings("unused")
- public boolean resumeAudioStream() {
- return sdlSession != null && sdlSession.resumeAudioStream();
- }
-
- private void NavServiceStarted() {
- navServiceStartResponseReceived = true;
- navServiceStartResponse = true;
- }
-
- private void NavServiceStartedNACK(List<String> rejectedParams) {
- navServiceStartResponseReceived = true;
- navServiceStartResponse = false;
- navServiceStartRejectedParams = rejectedParams;
- }
-
- private void AudioServiceStarted() {
- pcmServiceStartResponseReceived = true;
- pcmServiceStartResponse = true;
- }
-
- private void RPCProtectedServiceStarted() {
- rpcProtectedResponseReceived = true;
- rpcProtectedStartResponse = true;
- }
- private void AudioServiceStartedNACK(List<String> rejectedParams) {
- pcmServiceStartResponseReceived = true;
- pcmServiceStartResponse = false;
- pcmServiceStartRejectedParams = rejectedParams;
- }
-
- private void NavServiceEnded() {
- navServiceEndResponseReceived = true;
- navServiceEndResponse = true;
- }
-
- private void NavServiceEndedNACK() {
- navServiceEndResponseReceived = true;
- navServiceEndResponse = false;
- }
-
- private void AudioServiceEnded() {
- pcmServiceEndResponseReceived = true;
- pcmServiceEndResponse = true;
- }
-
- private void AudioServiceEndedNACK() {
- pcmServiceEndResponseReceived = true;
- pcmServiceEndResponse = false;
- }
-
- public void setAppService(Service mService)
- {
- _appService = mService;
- }
-
- @SuppressWarnings("unused")
- public boolean startProtectedRPCService() {
- rpcProtectedResponseReceived = false;
- rpcProtectedStartResponse = false;
- sdlSession.startService(SessionType.RPC, sdlSession.getSessionId(), true);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- //noinspection StatementWithEmptyBody
- while (!rpcProtectedResponseReceived && !fTask.isDone());
- scheduler.shutdown();
-
- return rpcProtectedStartResponse;
- }
-
- @SuppressWarnings("unused")
- public void getLockScreenIcon(final OnLockScreenIconDownloadedListener l){
- if(lockScreenIconRequest == null){
- l.onLockScreenIconDownloadError(new SdlException("This version of SDL core may not support lock screen icons.",
- SdlExceptionCause.LOCK_SCREEN_ICON_NOT_SUPPORTED));
- return;
- }
-
- LockScreenManager lockMan = sdlSession.getLockScreenMan();
- Bitmap bitmap = lockMan.getLockScreenIcon();
-
- // read bitmap if it was already downloaded so we don't have to download it every time
- if(bitmap != null){
- l.onLockScreenIconDownloaded(bitmap);
- }
- else{
- String url = lockScreenIconRequest.getUrl();
- sdlSession.getLockScreenMan().downloadLockScreenIcon(url, l);
- }
- }
-
- /* ******************* Public Helper Methods *************************/
-
- /*Begin V1 Enhanced helper*/
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param parentID -Menu parent ID for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- *@param IconType -Describes whether the image is static or dynamic
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void addCommand(@NonNull Integer commandID,
- String menuText, Integer parentID, Integer position,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
- throws SdlException {
-
-
- AddCommand msg = new AddCommand(commandID);
- msg.setCorrelationID(correlationID);
-
- if (vrCommands != null) msg.setVrCommands(vrCommands);
-
- Image cmdIcon = null;
-
- if (IconValue != null && IconType != null)
- {
- cmdIcon = new Image();
- cmdIcon.setValue(IconValue);
- cmdIcon.setImageType(IconType);
- }
-
- if (cmdIcon != null) msg.setCmdIcon(cmdIcon);
-
- if(menuText != null || parentID != null || position != null) {
- MenuParams menuParams = new MenuParams();
- menuParams.setMenuName(menuText);
- menuParams.setPosition(position);
- menuParams.setParentID(parentID);
- msg.setMenuParams(menuParams);
- }
-
- sendRPCRequest(msg);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- *@param IconType -Describes whether the image is static or dynamic
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Integer position,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, position, vrCommands, IconValue, IconType, correlationID);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- *@param IconType -Describes whether the image is static or dynamic
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Integer position, String IconValue, ImageType IconType,
- Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, position, null, IconValue, IconType, correlationID);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- *@param IconType -Describes whether the image is static or dynamic
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, String IconValue, ImageType IconType, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, null, null, IconValue, IconType, correlationID);
- }
-
- /**
- * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param commandID -Unique command ID of the command to add.
- * @param menuText -Menu text for optional sub value containing menu parameters.
- * @param vrCommands -VR synonyms for this AddCommand.
- * @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- * @param IconType -Describes whether the image is static or dynamic
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, null, vrCommands, IconValue, IconType, correlationID);
- }
-
- /**
- * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param commandID -Unique command ID of the command to add.
- * @param vrCommands -VR synonyms for this AddCommand.
- * @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
- * @param IconType -Describes whether the image is static or dynamic
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, null, null, null, vrCommands, IconValue, IconType, correlationID);
- }
-
- /*End V1 Enhanced helper*/
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param parentID -Menu parent ID for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void addCommand(@NonNull Integer commandID,
- String menuText, Integer parentID, Integer position,
- Vector<String> vrCommands, Integer correlationID)
- throws SdlException {
-
- AddCommand msg = new AddCommand(commandID);
- msg.setCorrelationID(correlationID);
- msg.setVrCommands(vrCommands);
- if(menuText != null || parentID != null || position != null) {
- MenuParams menuParams = new MenuParams();
- menuParams.setMenuName(menuText);
- menuParams.setPosition(position);
- menuParams.setParentID(parentID);
- msg.setMenuParams(menuParams);
- }
-
- sendRPCRequest(msg);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Integer position,
- Vector<String> vrCommands, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, position, vrCommands, correlationID);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param position -Menu position for optional sub value containing menu parameters.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Integer position,
- Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, position, null, correlationID);
- }
-
- /**
- *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Integer correlationID)
- throws SdlException {
- addCommand(commandID, menuText, null, null, (Vector<String>)null, correlationID);
- }
-
- /**
- * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param menuText -Menu text for optional sub value containing menu parameters.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- String menuText, Vector<String> vrCommands, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, menuText, null, null, vrCommands, correlationID);
- }
-
- /**
- * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- *@param commandID -Unique command ID of the command to add.
- *@param vrCommands -VR synonyms for this AddCommand.
- *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void addCommand(Integer commandID,
- Vector<String> vrCommands, Integer correlationID)
- throws SdlException {
-
- addCommand(commandID, null, null, null, vrCommands, correlationID);
- }
-
- /**
- * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param menuID -Unique ID of the sub menu to add.
- * @param menuName -Text to show in the menu for this sub menu.
- * @param position -Position within the items that are are at top level of the in application menu.
- * @param menuIcon -Image to be be shown along with the submenu item
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void addSubMenu(@NonNull Integer menuID, @NonNull String menuName,
- Integer position, Image menuIcon, Integer correlationID)
- throws SdlException {
-
- AddSubMenu msg = new AddSubMenu(menuID, menuName);
- msg.setCorrelationID(correlationID);
- msg.setPosition(position);
- msg.setMenuIcon(menuIcon);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param menuID -Unique ID of the sub menu to add.
- * @param menuName -Text to show in the menu for this sub menu.
- * @param position -Position within the items that are are at top level of the in application menu.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @Deprecated
- @SuppressWarnings("SameParameterValue")
- public void addSubMenu(@NonNull Integer menuID, @NonNull String menuName,
- Integer position, Integer correlationID)
- throws SdlException {
-
- addSubMenu(menuID, menuName, position, null, correlationID);
- }
-
- /**
- * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param menuID -Unique ID of the sub menu to add.
- * @param menuName -Text to show in the menu for this sub menu.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @Deprecated
- @SuppressWarnings("unused")
- public void addSubMenu(Integer menuID, String menuName,
- Integer correlationID) throws SdlException {
-
- addSubMenu(menuID, menuName, null, null, correlationID);
- }
-
- /*Begin V1 Enhanced helper*/
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsText -The text to speech message in the form of a string.
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param alertText3 -The optional third line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param softButtons -A list of App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void alert(String ttsText, String alertText1,
- String alertText2, String alertText3, Boolean playTone, Integer duration, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
-
- Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(ttsText);
- Alert msg = new Alert();
- msg.setCorrelationID(correlationID);
- msg.setAlertText1(alertText1);
- msg.setAlertText2(alertText2);
- msg.setAlertText3(alertText3);
- msg.setDuration(duration);
- msg.setPlayTone(playTone);
- msg.setTtsChunks(chunks);
- msg.setSoftButtons(softButtons);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsChunks -Text/phonemes to speak in the form of ttsChunks.
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param alertText3 -The optional third line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param softButtons -A list of App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- public void alert(Vector<TTSChunk> ttsChunks,
- String alertText1, String alertText2, String alertText3, Boolean playTone,
- Integer duration, Vector<SoftButton> softButtons, Integer correlationID) throws SdlException {
-
- Alert msg = new Alert();
- msg.setCorrelationID(correlationID);
- msg.setAlertText1(alertText1);
- msg.setAlertText2(alertText2);
- msg.setAlertText3(alertText3);
- msg.setDuration(duration);
- msg.setPlayTone(playTone);
- msg.setTtsChunks(ttsChunks);
- msg.setSoftButtons(softButtons);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsText -The text to speech message in the form of a string.
- * @param playTone -Defines if tone should be played.
- * @param softButtons -A list of App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(String ttsText, Boolean playTone, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
-
- alert(ttsText, null, null, null, playTone, null, softButtons, correlationID);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param chunks -A list of text/phonemes to speak in the form of ttsChunks.
- * @param playTone -Defines if tone should be played.
- * @param softButtons -A list of App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(Vector<TTSChunk> chunks, Boolean playTone, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
-
- alert(chunks, null, null, null, playTone, null, softButtons, correlationID);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param alertText3 -The optional third line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param softButtons -A list of App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(String alertText1, String alertText2, String alertText3,
- Boolean playTone, Integer duration, Vector<SoftButton> softButtons, Integer correlationID)
- throws SdlException {
-
- alert((Vector<TTSChunk>)null, alertText1, alertText2, alertText3, playTone, duration, softButtons, correlationID);
- }
-
- /*End V1 Enhanced helper*/
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsText -The text to speech message in the form of a string.
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void alert(String ttsText, String alertText1,
- String alertText2, Boolean playTone, Integer duration,
- Integer correlationID) throws SdlException {
-
- Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(ttsText);
- Alert msg = new Alert();
- msg.setCorrelationID(correlationID);
- msg.setAlertText1(alertText1);
- msg.setAlertText2(alertText2);
- msg.setDuration(duration);
- msg.setPlayTone(playTone);
- msg.setTtsChunks(chunks);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsChunks -A list of text/phonemes to speak in the form of ttsChunks.
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- public void alert(Vector<TTSChunk> ttsChunks,
- String alertText1, String alertText2, Boolean playTone,
- Integer duration, Integer correlationID) throws SdlException {
-
- Alert msg = new Alert();
- msg.setCorrelationID(correlationID);
- msg.setAlertText1(alertText1);
- msg.setAlertText2(alertText2);
- msg.setDuration(duration);
- msg.setPlayTone(playTone);
- msg.setTtsChunks(ttsChunks);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsText -The text to speech message in the form of a string.
- * @param playTone -Defines if tone should be played.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(String ttsText, Boolean playTone,
- Integer correlationID) throws SdlException {
-
- alert(ttsText, null, null, playTone, null, correlationID);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param chunks -A list of text/phonemes to speak in the form of ttsChunks.
- * @param playTone -Defines if tone should be played.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(Vector<TTSChunk> chunks, Boolean playTone,
- Integer correlationID) throws SdlException {
-
- alert(chunks, null, null, playTone, null, correlationID);
- }
-
- /**
- * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param alertText1 -The first line of the alert text field.
- * @param alertText2 -The second line of the alert text field.
- * @param playTone -Defines if tone should be played.
- * @param duration -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void alert(String alertText1, String alertText2,
- Boolean playTone, Integer duration, Integer correlationID)
- throws SdlException {
-
- alert((Vector<TTSChunk>)null, alertText1, alertText2, playTone, duration, correlationID);
- }
-
- /**
- * Sends a CreateInteractionChoiceSet RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param choiceSet to be sent to the module
- * @param interactionChoiceSetID to be used in reference to the supplied choiceSet
- * @param correlationID to be set to the RPCRequest
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void createInteractionChoiceSet(
- @NonNull Vector<Choice> choiceSet, @NonNull Integer interactionChoiceSetID,
- Integer correlationID) throws SdlException {
-
- CreateInteractionChoiceSet msg = new CreateInteractionChoiceSet(interactionChoiceSetID, choiceSet);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a DeleteCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param commandID -ID of the command(s) to delete.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void deleteCommand(@NonNull Integer commandID,
- Integer correlationID) throws SdlException {
-
- DeleteCommand msg = new DeleteCommand(commandID);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a DeleteInteractionChoiceSet RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param interactionChoiceSetID -ID of the interaction choice set to delete.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void deleteInteractionChoiceSet(
- @NonNull Integer interactionChoiceSetID, Integer correlationID)
- throws SdlException {
-
- DeleteInteractionChoiceSet msg = new DeleteInteractionChoiceSet(interactionChoiceSetID);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a DeleteSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param menuID -The menuID of the submenu to delete.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void deleteSubMenu(Integer menuID,
- Integer correlationID) throws SdlException {
-
- DeleteSubMenu msg = new DeleteSubMenu(menuID);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
-
- /*Begin V1 Enhanced helper*/
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
- * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Integer interactionChoiceSetID, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
-
- Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>();
- interactionChoiceSetIDs.add(interactionChoiceSetID);
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, InteractionMode.BOTH, interactionChoiceSetIDs);
- msg.setInitialPrompt(initChunks);
- msg.setVrHelp(vrHelp);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
- * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Integer interactionChoiceSetID,
- String helpPrompt, String timeoutPrompt,
- @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
-
- Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>();
- interactionChoiceSetIDs.add(interactionChoiceSetID);
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt);
- Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDs);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setVrHelp(vrHelp);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction.
- * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Vector<Integer> interactionChoiceSetIDList,
- String helpPrompt, String timeoutPrompt,
- @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
-
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt);
- Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setVrHelp(vrHelp);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initChunks -A list of text/phonemes to speak for the initial prompt in the form of ttsChunks.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction.
- * @param helpChunks -A list of text/phonemes to speak for the help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutChunks A list of text/phonems to speak for the timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(
- Vector<TTSChunk> initChunks, @NonNull String displayText,
- @NonNull Vector<Integer> interactionChoiceSetIDList,
- Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks,
- @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
-
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setVrHelp(vrHelp);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /*End V1 Enhanced*/
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Integer interactionChoiceSetID,
- Integer correlationID) throws SdlException {
-
- Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>();
- interactionChoiceSetIDs.add(interactionChoiceSetID);
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, InteractionMode.BOTH, interactionChoiceSetIDs);
- msg.setInitialPrompt(initChunks);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
- * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Integer interactionChoiceSetID,
- String helpPrompt, String timeoutPrompt,
- @NonNull InteractionMode interactionMode, Integer timeout,
- Integer correlationID) throws SdlException {
-
- Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>();
- interactionChoiceSetIDs.add(interactionChoiceSetID);
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt);
- Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDs);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initPrompt -Intial prompt spoken to the user at the start of an interaction.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction.
- * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(String initPrompt,
- @NonNull String displayText, @NonNull Vector<Integer> interactionChoiceSetIDList,
- String helpPrompt, String timeoutPrompt,
- @NonNull InteractionMode interactionMode, Integer timeout,
- Integer correlationID) throws SdlException {
-
- Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt);
- Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt);
- Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt);
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param initChunks -A list of text/phonemes to speak for the initial prompt in the form of ttsChunks.
- * @param displayText -Text to be displayed first.
- * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction.
- * @param helpChunks -A list of text/phonemes to speak for the help text that is spoken when a user speaks "help" during the interaction.
- * @param timeoutChunks A list of text/phonems to speak for the timeout text that is spoken when a VR interaction times out.
- * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
- * @param timeout -Timeout in milliseconds.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performInteraction(
- Vector<TTSChunk> initChunks, @NonNull String displayText,
- @NonNull Vector<Integer> interactionChoiceSetIDList,
- Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks,
- @NonNull InteractionMode interactionMode, Integer timeout,
- Integer correlationID) throws SdlException {
-
- PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList);
- msg.setInitialPrompt(initChunks);
- msg.setTimeout(timeout);
- msg.setHelpPrompt(helpChunks);
- msg.setTimeoutPrompt(timeoutChunks);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- // Protected registerAppInterface used to ensure only non-ALM applications call
- // reqisterAppInterface
- protected void registerAppInterfacePrivate(
- @NonNull SdlMsgVersion sdlMsgVersion, @NonNull String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, @NonNull Boolean isMediaApp,
- @NonNull Language languageDesired, @NonNull Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType,
- @NonNull String appID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, Integer correlationID)
- throws SdlException {
- String carrierName = null;
- if(telephonyManager != null){
- carrierName = telephonyManager.getNetworkOperatorName();
- }
-
- DeviceInfo deviceInfo = new DeviceInfo();
- deviceInfo.setHardware(android.os.Build.MODEL);
- deviceInfo.setOs(DeviceInfo.DEVICE_OS);
- deviceInfo.setOsVersion(Build.VERSION.RELEASE);
- deviceInfo.setCarrier(carrierName);
-
- if (sdlMsgVersion == null) {
- sdlMsgVersion = new SdlMsgVersion();
- if(protocolVersion.getMajor() == 1) {
- DebugTool.logInfo("Connected to an older module, must send 1.0.0 as RPC spec");
- sdlMsgVersion.setMajorVersion(1);
- sdlMsgVersion.setMinorVersion(0);
- }else {
- sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor());
- sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor());
- }
- }
- if (languageDesired == null) {
- languageDesired = Language.EN_US;
- }
- if (hmiDisplayLanguageDesired == null) {
- hmiDisplayLanguageDesired = Language.EN_US;
- }
-
- RegisterAppInterface msg = new RegisterAppInterface(sdlMsgVersion, appName, isMediaApp, languageDesired, hmiDisplayLanguageDesired, appID);
-
- if (correlationID != null) {
- msg.setCorrelationID(correlationID);
- }
-
- msg.setDeviceInfo(deviceInfo);
-
- msg.setTtsName(ttsName);
-
- if (ngnMediaScreenAppName == null) {
- ngnMediaScreenAppName = appName;
- }
-
- msg.setNgnMediaScreenAppName(ngnMediaScreenAppName);
-
- if (vrSynonyms == null) {
- vrSynonyms = new Vector<String>();
- vrSynonyms.add(appName);
- }
- msg.setVrSynonyms(vrSynonyms);
-
- msg.setAppHMIType(appType);
-
- msg.setDayColorScheme(dayColorScheme);
- msg.setNightColorScheme(nightColorScheme);
-
- if (_bAppResumeEnabled)
- {
- if (_lastHashID != null)
- msg.setHashID(_lastHashID);
- }
-
- Intent sendIntent = createBroadcastIntent();
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.REGISTER_APP_INTERFACE.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_REQUEST);
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- sendBroadcastIntent(sendIntent);
-
- sendRPCMessagePrivate(msg);
- }
-
- /*Begin V1 Enhanced helper function*/
-
- /**
- * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpPrompt that will be used for the VR screen
- * @param timeoutPrompt string to be displayed after timeout
- * @param vrHelpTitle string that may be displayed on VR prompt dialog
- * @param vrHelp a list of VR synonyms that may be displayed to user
- * @param correlationID to be attached to the request
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setGlobalProperties(
- String helpPrompt, String timeoutPrompt, String vrHelpTitle, Vector<VrHelpItem> vrHelp, Integer correlationID)
- throws SdlException {
-
- SetGlobalProperties req = new SetGlobalProperties();
- req.setCorrelationID(correlationID);
- req.setHelpPrompt(TTSChunkFactory.createSimpleTTSChunks(helpPrompt));
- req.setTimeoutPrompt(TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt));
- req.setVrHelpTitle(vrHelpTitle);
- req.setVrHelp(vrHelp);
-
- sendRPCRequest(req);
- }
-
- /**
- * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpChunks tts chunks that should be used when prompting the user
- * @param timeoutChunks tts chunks that will be used when a timeout occurs
- * @param vrHelpTitle string that may be displayed on VR prompt dialog
- * @param vrHelp a list of VR synonyms that may be displayed to user
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setGlobalProperties(
- Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, String vrHelpTitle, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
-
- SetGlobalProperties req = new SetGlobalProperties();
- req.setCorrelationID(correlationID);
- req.setHelpPrompt(helpChunks);
- req.setTimeoutPrompt(timeoutChunks);
- req.setVrHelpTitle(vrHelpTitle);
- req.setVrHelp(vrHelp);
-
- sendRPCRequest(req);
- }
-
- /*End V1 Enhanced helper function*/
-
- /**
- * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpPrompt that will be used for the VR screen
- * @param timeoutPrompt string to be displayed after timeout
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setGlobalProperties(
- String helpPrompt, String timeoutPrompt, Integer correlationID)
- throws SdlException {
-
- SetGlobalProperties req = new SetGlobalProperties();
- req.setCorrelationID(correlationID);
- req.setHelpPrompt(TTSChunkFactory.createSimpleTTSChunks(helpPrompt));
- req.setTimeoutPrompt(TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt));
-
- sendRPCRequest(req);
- }
-
- /**
- * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpChunks tts chunks that should be used when prompting the user
- * @param timeoutChunks tts chunks that will be used when a timeout occurs
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setGlobalProperties(
- Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks,
- Integer correlationID) throws SdlException {
-
- SetGlobalProperties req = new SetGlobalProperties();
- req.setCorrelationID(correlationID);
- req.setHelpPrompt(helpChunks);
- req.setTimeoutPrompt(timeoutChunks);
-
- sendRPCRequest(req);
- }
-
- @SuppressWarnings("unused")
- public void resetGlobalProperties(Vector<GlobalProperty> properties,
- Integer correlationID) throws SdlException {
-
- ResetGlobalProperties req = new ResetGlobalProperties();
-
- req.setCorrelationID(correlationID);
- req.setProperties(properties);
-
- sendRPCRequest(req);
- }
-
-
- /**
- * Sends a SetMediaClockTimer RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param hours integer for hours
- * @param minutes integer for minutes
- * @param seconds integer for seconds
- * @param updateMode mode in which the media clock timer should be updated
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setMediaClockTimer(Integer hours,
- Integer minutes, Integer seconds, @NonNull UpdateMode updateMode,
- Integer correlationID) throws SdlException {
-
- SetMediaClockTimer msg = new SetMediaClockTimer(updateMode);
- if (hours != null || minutes != null || seconds != null) {
- StartTime startTime = new StartTime(hours, minutes, seconds);
- msg.setStartTime(startTime);
- }
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Pauses the media clock. Responses are captured through callback on IProxyListener.
- *
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void pauseMediaClockTimer(Integer correlationID)
- throws SdlException {
-
- SetMediaClockTimer msg = new SetMediaClockTimer(UpdateMode.PAUSE);
- StartTime startTime = new StartTime(0, 0, 0);
- msg.setStartTime(startTime);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Resumes the media clock. Responses are captured through callback on IProxyListener.
- *
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void resumeMediaClockTimer(Integer correlationID)
- throws SdlException {
-
- SetMediaClockTimer msg = new SetMediaClockTimer(UpdateMode.RESUME);
- StartTime startTime = new StartTime(0, 0, 0);
- msg.setStartTime(startTime);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Clears the media clock. Responses are captured through callback on IProxyListener.
- *
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void clearMediaClockTimer(Integer correlationID)
- throws SdlException {
-
- Show msg = new Show();
- msg.setCorrelationID(correlationID);
- msg.setMediaClock(" ");
-
- sendRPCRequest(msg);
- }
-
- /*Begin V1 Enhanced helper*/
- /**
- * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param mainText1 text displayed in a single or upper display line.
- * @param mainText2 text displayed on the second display line.
- * @param mainText3 text displayed on the second "page" first display line.
- * @param mainText4 text displayed on the second "page" second display line.
- * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps)
- * @param mediaClock text value for MediaClock field.
- * @param mediaTrack text displayed in the track field.
- * @param graphic image struct determining whether static or dynamic image to display in app.
- * @param softButtons app defined SoftButtons.
- * @param customPresets app labeled on-screen presets.
- * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void show(String mainText1, String mainText2, String mainText3, String mainText4,
- String statusBar, String mediaClock, String mediaTrack,
- Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
- TextAlignment alignment, Integer correlationID)
- throws SdlException {
-
- Show msg = new Show();
- msg.setCorrelationID(correlationID);
- msg.setMainField1(mainText1);
- msg.setMainField2(mainText2);
- msg.setStatusBar(statusBar);
- msg.setMediaClock(mediaClock);
- msg.setMediaTrack(mediaTrack);
- msg.setAlignment(alignment);
- msg.setMainField3(mainText3);
- msg.setMainField4(mainText4);
- msg.setGraphic(graphic);
- msg.setSoftButtons(softButtons);
- msg.setCustomPresets(customPresets);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param mainText1 -Text displayed in a single or upper display line.
- * @param mainText2 -Text displayed on the second display line.
- * @param mainText3 -Text displayed on the second "page" first display line.
- * @param mainText4 -Text displayed on the second "page" second display line.
- * @param graphic -Image struct determining whether static or dynamic image to display in app.
- * @param softButtons -App defined SoftButtons.
- * @param customPresets -App labeled on-screen presets.
- * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void show(String mainText1, String mainText2, String mainText3, String mainText4,
- Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
- TextAlignment alignment, Integer correlationID)
- throws SdlException {
-
- show(mainText1, mainText2, mainText3, mainText4, null, null, null, graphic, softButtons, customPresets, alignment, correlationID);
- }
- /*End V1 Enhanced helper*/
-
- /**
- * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param mainText1 text displayed in a single or upper display line.
- * @param mainText2 text displayed on the second display line.
- * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps)
- * @param mediaClock text value for MediaClock field.
- * @param mediaTrack text displayed in the track field.
- * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("SameParameterValue")
- public void show(String mainText1, String mainText2,
- String statusBar, String mediaClock, String mediaTrack,
- TextAlignment alignment, Integer correlationID)
- throws SdlException {
-
- Show msg = new Show();
- msg.setCorrelationID(correlationID);
- msg.setMainField1(mainText1);
- msg.setMainField2(mainText2);
- msg.setStatusBar(statusBar);
- msg.setMediaClock(mediaClock);
- msg.setMediaTrack(mediaTrack);
- msg.setAlignment(alignment);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param mainText1 -Text displayed in a single or upper display line.
- * @param mainText2 -Text displayed on the second display line.
- * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void show(String mainText1, String mainText2,
- TextAlignment alignment, Integer correlationID)
- throws SdlException {
-
- show(mainText1, mainText2, null, null, null, alignment, correlationID);
- }
-
- /**
- * Sends a Speak RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsText -The text to speech message in the form of a string.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void speak(@NonNull String ttsText, Integer correlationID)
- throws SdlException {
-
- Speak msg = new Speak(TTSChunkFactory.createSimpleTTSChunks(ttsText));
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a Speak RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param ttsChunks -Text/phonemes to speak in the form of ttsChunks.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void speak(@NonNull Vector<TTSChunk> ttsChunks,
- Integer correlationID) throws SdlException {
-
- Speak msg = new Speak(ttsChunks);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Sends a SubscribeButton RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param buttonName -Name of the button to subscribe.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void subscribeButton(@NonNull ButtonName buttonName,
- Integer correlationID) throws SdlException {
-
- SubscribeButton msg = new SubscribeButton(buttonName);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- // Protected unregisterAppInterface used to ensure no non-ALM app calls
- // unregisterAppInterface.
- protected void unregisterAppInterfacePrivate(Integer correlationID)
- throws SdlException {
-
- UnregisterAppInterface msg = new UnregisterAppInterface();
- msg.setCorrelationID(correlationID);
-
- Intent sendIntent = createBroadcastIntent();
-
- updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString());
- updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_REQUEST);
- updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID());
- updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg));
- sendBroadcastIntent(sendIntent);
-
- sendRPCMessagePrivate(msg);
- }
-
- /**
- * Sends an UnsubscribeButton RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param buttonName -Name of the button to unsubscribe.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void unsubscribeButton(@NonNull ButtonName buttonName,
- Integer correlationID) throws SdlException {
-
- UnsubscribeButton msg = new UnsubscribeButton(buttonName);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Creates a choice to be added to a choiceset. Choice has both a voice and a visual menu component.
- *
- * @param choiceID -Unique ID used to identify this choice (returned in callback).
- * @param choiceMenuName -Text name displayed for this choice.
- * @param choiceVrCommands -Vector of vrCommands used to select this choice by voice. Must contain
- * at least one non-empty element.
- * @return Choice created.
- */
- @SuppressWarnings("unused")
- public Choice createChoiceSetChoice(Integer choiceID, String choiceMenuName,
- Vector<String> choiceVrCommands) {
- Choice returnChoice = new Choice();
-
- returnChoice.setChoiceID(choiceID);
- returnChoice.setMenuName(choiceMenuName);
- returnChoice.setVrCommands(choiceVrCommands);
-
- return returnChoice;
- }
-
- /**
- * Starts audio pass thru session. Responses are captured through callback on IProxyListener.
- *
- * @param initialPrompt -SDL will speak this prompt before opening the audio pass thru session.
- * @param audioPassThruDisplayText1 -First line of text displayed during audio capture.
- * @param audioPassThruDisplayText2 -Second line of text displayed during audio capture.
- * @param samplingRate -Allowable values of 8 khz or 16 or 22 or 44 khz.
- * @param maxDuration -The maximum duration of audio recording in milliseconds.
- * @param bitsPerSample -Specifies the quality the audio is recorded. Currently 8 bit or 16 bit.
- * @param audioType -Specifies the type of audio data being requested.
- * @param muteAudio -Defines if the current audio source should be muted during the APT session.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void performaudiopassthru(String initialPrompt, String audioPassThruDisplayText1, String audioPassThruDisplayText2,
- @NonNull SamplingRate samplingRate, @NonNull Integer maxDuration, @NonNull BitsPerSample bitsPerSample,
- @NonNull AudioType audioType, Boolean muteAudio, Integer correlationID) throws SdlException {
- Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(initialPrompt);
- PerformAudioPassThru msg = new PerformAudioPassThru(samplingRate, maxDuration, bitsPerSample, audioType);
- msg.setCorrelationID(correlationID);
- msg.setInitialPrompt(chunks);
- msg.setAudioPassThruDisplayText1(audioPassThruDisplayText1);
- msg.setAudioPassThruDisplayText2(audioPassThruDisplayText2);
- msg.setMuteAudio(muteAudio);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Ends audio pass thru session. Responses are captured through callback on IProxyListener.
- *
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void endaudiopassthru(Integer correlationID) throws SdlException
- {
- EndAudioPassThru msg = new EndAudioPassThru();
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Subscribes for specific published data items. The data will be only sent if it has changed.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Subscribes to GPS data.
- * @param speed -Subscribes to vehicle speed data in kilometers per hour.
- * @param rpm -Subscribes to number of revolutions per minute of the engine.
- * @param fuelLevel -Subscribes to fuel level in the tank (percentage).
- * @param fuelLevel_State -Subscribes to fuel level state.
- * @param instantFuelConsumption -Subscribes to instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Subscribes to the external temperature in degrees celsius.
- * @param prndl -Subscribes to PRNDL data that houses the selected gear.
- * @param tirePressure -Subscribes to the TireStatus data containing status and pressure of tires.
- * @param odometer -Subscribes to Odometer data in km.
- * @param beltStatus -Subscribes to status of the seat belts.
- * @param bodyInformation -Subscribes to body information including power modes.
- * @param deviceStatus -Subscribes to device status including signal and battery strength.
- * @param driverBraking -Subscribes to the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void subscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
- boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- SubscribeVehicleData msg = new SubscribeVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Subscribes for specific published data items. The data will be only sent if it has changed.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Subscribes to GPS data.
- * @param speed -Subscribes to vehicle speed data in kilometers per hour.
- * @param rpm -Subscribes to number of revolutions per minute of the engine.
- * @param fuelLevel -Subscribes to fuel level in the tank (percentage).
- * @param fuelLevel_State -Subscribes to fuel level state.
- * @param instantFuelConsumption -Subscribes to instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Subscribes to the external temperature in degrees celsius.
- * @param prndl -Subscribes to PRNDL data that houses the selected gear.
- * @param tirePressure -Subscribes to the TireStatus data containing status and pressure of tires.
- * @param engineOilLife -Subscribes to Engine Oil Life data.
- * @param odometer -Subscribes to Odometer data in km.
- * @param beltStatus -Subscribes to status of the seat belts.
- * @param bodyInformation -Subscribes to body information including power modes.
- * @param deviceStatus -Subscribes to device status including signal and battery strength.
- * @param driverBraking -Subscribes to the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void subscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
- boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- SubscribeVehicleData msg = new SubscribeVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setEngineOilLife(engineOilLife);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Unsubscribes for specific published data items.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Unsubscribes to GPS data.
- * @param speed -Unsubscribes to vehicle speed data in kilometers per hour.
- * @param rpm -Unsubscribes to number of revolutions per minute of the engine.
- * @param fuelLevel -Unsubscribes to fuel level in the tank (percentage).
- * @param fuelLevel_State -Unsubscribes to fuel level state.
- * @param instantFuelConsumption -Unsubscribes to instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Unsubscribes to the external temperature in degrees celsius.
- * @param prndl -Unsubscribes to PRNDL data that houses the selected gear.
- * @param tirePressure -Unsubscribes to the TireStatus data containing status and pressure of tires.
- * @param odometer -Unsubscribes to Odometer data in km.
- * @param beltStatus -Unsubscribes to status of the seat belts.
- * @param bodyInformation -Unsubscribes to body information including power modes.
- * @param deviceStatus -Unsubscribes to device status including signal and battery strength.
- * @param driverBraking -Unsubscribes to the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
-
- @SuppressWarnings("unused")
- @Deprecated
- public void unsubscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
- boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- UnsubscribeVehicleData msg = new UnsubscribeVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Unsubscribes for specific published data items.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Unsubscribes to GPS data.
- * @param speed -Unsubscribes to vehicle speed data in kilometers per hour.
- * @param rpm -Unsubscribes to number of revolutions per minute of the engine.
- * @param fuelLevel -Unsubscribes to fuel level in the tank (percentage).
- * @param fuelLevel_State -Unsubscribes to fuel level state.
- * @param instantFuelConsumption -Unsubscribes to instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Unsubscribes to the external temperature in degrees celsius.
- * @param prndl -Unsubscribes to PRNDL data that houses the selected gear.
- * @param tirePressure -Unsubscribes to the TireStatus data containing status and pressure of tires.
- * @param engineOilLife -Unsubscribes to Engine Oil Life data.
- * @param odometer -Unsubscribes to Odometer data in km.
- * @param beltStatus -Unsubscribes to status of the seat belts.
- * @param bodyInformation -Unsubscribes to body information including power modes.
- * @param deviceStatus -Unsubscribes to device status including signal and battery strength.
- * @param driverBraking -Unsubscribes to the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
-
- @SuppressWarnings("unused")
- public void unsubscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
- boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- UnsubscribeVehicleData msg = new UnsubscribeVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setEngineOilLife(engineOilLife);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Performs a Non periodic vehicle data read request.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Performs an ad-hoc request for GPS data.
- * @param speed -Performs an ad-hoc request for vehicle speed data in kilometers per hour.
- * @param rpm -Performs an ad-hoc request for number of revolutions per minute of the engine.
- * @param fuelLevel -Performs an ad-hoc request for fuel level in the tank (percentage).
- * @param fuelLevel_State -Performs an ad-hoc request for fuel level state.
- * @param instantFuelConsumption -Performs an ad-hoc request for instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Performs an ad-hoc request for the external temperature in degrees celsius.
- * @param vin -Performs an ad-hoc request for the Vehicle identification number
- * @param prndl -Performs an ad-hoc request for PRNDL data that houses the selected gear.
- * @param tirePressure -Performs an ad-hoc request for the TireStatus data containing status and pressure of tires.
- * @param odometer -Performs an ad-hoc request for Odometer data in km.
- * @param beltStatus -Performs an ad-hoc request for status of the seat belts.
- * @param bodyInformation -Performs an ad-hoc request for body information including power modes.
- * @param deviceStatus -Performs an ad-hoc request for device status including signal and battery strength.
- * @param driverBraking -Performs an ad-hoc request for the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void getvehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure,
- boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- GetVehicleData msg = new GetVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setVin(vin);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Performs a Non periodic vehicle data read request.
- * Responses are captured through callback on IProxyListener.
- *
- * @param gps -Performs an ad-hoc request for GPS data.
- * @param speed -Performs an ad-hoc request for vehicle speed data in kilometers per hour.
- * @param rpm -Performs an ad-hoc request for number of revolutions per minute of the engine.
- * @param fuelLevel -Performs an ad-hoc request for fuel level in the tank (percentage).
- * @param fuelLevel_State -Performs an ad-hoc request for fuel level state.
- * @param instantFuelConsumption -Performs an ad-hoc request for instantaneous fuel consumption in microlitres.
- * @param externalTemperature -Performs an ad-hoc request for the external temperature in degrees celsius.
- * @param vin -Performs an ad-hoc request for the Vehicle identification number
- * @param prndl -Performs an ad-hoc request for PRNDL data that houses the selected gear.
- * @param tirePressure -Performs an ad-hoc request for the TireStatus data containing status and pressure of tires.
- * @param engineOilLife -Performs an ad-hoc request for Engine Oil Life data.
- * @param odometer -Performs an ad-hoc request for Odometer data in km.
- * @param beltStatus -Performs an ad-hoc request for status of the seat belts.
- * @param bodyInformation -Performs an ad-hoc request for body information including power modes.
- * @param deviceStatus -Performs an ad-hoc request for device status including signal and battery strength.
- * @param driverBraking -Performs an ad-hoc request for the status of the brake pedal.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void getvehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure,
- boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
- {
- GetVehicleData msg = new GetVehicleData();
- msg.setGps(gps);
- msg.setSpeed(speed);
- msg.setRpm(rpm);
- msg.setFuelLevel(fuelLevel);
- msg.setFuelLevel_State(fuelLevel_State);
- msg.setInstantFuelConsumption(instantFuelConsumption);
- msg.setExternalTemperature(externalTemperature);
- msg.setVin(vin);
- msg.setPrndl(prndl);
- msg.setTirePressure(tirePressure);
- msg.setEngineOilLife(engineOilLife);
- msg.setOdometer(odometer);
- msg.setBeltStatus(beltStatus);
- msg.setBodyInformation(bodyInformation);
- msg.setDeviceStatus(deviceStatus);
- msg.setDriverBraking(driverBraking);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Creates a full screen overlay containing a large block of formatted text that can be scrolled with up to 8 SoftButtons defined.
- * Responses are captured through callback on IProxyListener.
- *
- * @param scrollableMessageBody -Body of text that can include newlines and tabs.
- * @param timeout -App defined timeout. Indicates how long of a timeout from the last action.
- * @param softButtons -App defined SoftButtons.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void scrollablemessage(@NonNull String scrollableMessageBody, Integer timeout, Vector<SoftButton> softButtons, Integer correlationID) throws SdlException
- {
- ScrollableMessage msg = new ScrollableMessage(scrollableMessageBody);
- msg.setCorrelationID(correlationID);
- msg.setTimeout(timeout);
- msg.setSoftButtons(softButtons);
-
- sendRPCRequest(msg);
- }
-
-
- /**
- * Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider.
- * Responses are captured through callback on IProxyListener.
- *
- * @param numTicks -Number of selectable items on a horizontal axis.
- * @param position -Initial position of slider control (cannot exceed numTicks).
- * @param sliderHeader -Text header to display.
- * @param sliderFooter - Text footer to display (meant to display min/max threshold descriptors).
- * @param timeout -App defined timeout. Indicates how long of a timeout from the last action.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void slider(@NonNull Integer numTicks, @NonNull Integer position, @NonNull String sliderHeader, Vector<String> sliderFooter, Integer timeout, Integer correlationID) throws SdlException
- {
- Slider msg = new Slider(numTicks, position, sliderHeader);
- msg.setCorrelationID(correlationID);
- msg.setSliderFooter(sliderFooter);
- msg.setTimeout(timeout);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Responses are captured through callback on IProxyListener.
- *
- * @param language requested SDL voice engine (VR+TTS) language registration
- * @param hmiDisplayLanguage request display language registration.
- * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void changeregistration(@NonNull Language language, @NonNull Language hmiDisplayLanguage, Integer correlationID) throws SdlException
- {
- ChangeRegistration msg = new ChangeRegistration(language, hmiDisplayLanguage);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile device.
- * Responses are captured through callback on IProxyListener.
- *
- * @param is - The input stream of byte data that putFileStream will read from
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of the file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param iLength - The total length of the file being sent.
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(InputStream, String, Long, Long)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(iOffset);
- msg.setLength(iLength);
-
- startRPCStream(is, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param inputStream The input stream of byte data that will be read from.
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param length The total length of the file being sent.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length) throws SdlException {
- PutFile msg = new PutFile(fileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(offset);
- msg.setLength(length);
-
- startRPCStream(inputStream, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile device.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param iLength - The total length of the file being sent.
- *
- * @return OutputStream - The output stream of byte data that is written to by the app developer
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(String, Long, Long)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public OutputStream putFileStream(@NonNull String sdlFileName, Integer iOffset, Integer iLength) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(iOffset);
- msg.setLength(iLength);
-
- return startRPCStream(msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param length The total length of the file being sent.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length) throws SdlException {
- PutFile msg = new PutFile(fileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(offset);
- msg.setLength(length);
-
- return startRPCStream(msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile device.
- * Responses are captured through callback on IProxyListener.
- *
- * @param is - The input stream of byte data that PutFileStream will read from
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of the file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param iLength - The total length of the file being sent.
- * @param fileType - The selected file type -- see the FileType enumeration for details
- * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, fileType);
- msg.setCorrelationID(10000);
- msg.setPersistentFile(bPersistentFile);
- msg.setSystemFile(bSystemFile);
- msg.setOffset(iOffset);
- msg.setLength(iLength);
-
- startRPCStream(is, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param inputStream The input stream of byte data that will be read from.
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param length The total length of the file being sent.
- * @param fileType The selected file type. See the {@link FileType} enum for
- * details.
- * @param isPersistentFile Indicates if the file is meant to persist between
- * sessions / ignition cycles.
- * @param isSystemFile Indicates if the file is meant to be passed through
- * core to elsewhere in the system.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException {
- PutFile msg = new PutFile(fileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(offset);
- msg.setLength(length);
- msg.setOnPutFileUpdateListener(cb);
- startRPCStream(inputStream, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile device.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param iLength - The total length of the file being sent.
- * @param fileType - The selected file type -- see the FileType enumeration for details
- * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @return OutputStream - The output stream of byte data that is written to by the app developer
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public OutputStream putFileStream(@NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, fileType);
- msg.setCorrelationID(10000);
- msg.setPersistentFile(bPersistentFile);
- msg.setSystemFile(bSystemFile);
- msg.setOffset(iOffset);
- msg.setLength(iLength);
-
- return startRPCStream(msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param length The total length of the file being sent.
- * @param fileType The selected file type. See the {@link FileType} enum for
- * details.
- * @param isPersistentFile Indicates if the file is meant to persist between
- * sessions / ignition cycles.
- * @param isSystemFile Indicates if the file is meant to be passed through
- * core to elsewhere in the system.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException {
- PutFile msg = new PutFile(fileName, FileType.BINARY);
- msg.setCorrelationID(10000);
- msg.setSystemFile(true);
- msg.setOffset(offset);
- msg.setLength(length);
- msg.setOnPutFileUpdateListener(cb);
-
- return startRPCStream(msg);
- }
-
- /**
- * Used to push a stream of putfile RPC's containing binary data from a mobile device to the module.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sPath - The physical file path on the mobile device.
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param fileType - The selected file type -- see the FileType enumeration for details
- * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse.
- * @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(String, String, Long, FileType, Boolean, Boolean, Boolean, Integer, OnPutFileUpdateListener)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public RPCStreamController putFileStream(String sPath, @NonNull String sdlFileName, Integer iOffset, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, fileType);
- msg.setCorrelationID(iCorrelationID);
- msg.setPersistentFile(bPersistentFile);
- msg.setSystemFile(bSystemFile);
- msg.setOffset(iOffset);
- msg.setLength(0);
-
- return startPutFileStream(sPath, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param path The physical file path on the mobile device.
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param fileType The selected file type. See the {@link FileType} enum for
- * details.
- * @param isPersistentFile Indicates if the file is meant to persist between
- * sessions / ignition cycles.
- * @param isSystemFile Indicates if the file is meant to be passed through
- * core to elsewhere in the system.
- * @param correlationId A unique id that correlates each RPCRequest and
- * RPCResponse.
- * @return RPCStreamController If the putFileStream was not started
- * successfully null is returned, otherwise a valid object reference is
- * returned .
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public RPCStreamController putFileStream(String path, @NonNull String fileName, Long offset, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId, OnPutFileUpdateListener cb ) throws SdlException {
- PutFile msg = new PutFile(fileName, fileType);
- msg.setCorrelationID(correlationId);
- msg.setPersistentFile(isPersistentFile);
- msg.setSystemFile(isSystemFile);
- msg.setOffset(offset);
- msg.setLength(0L);
- msg.setPayloadProtected(isPayloadProtected);
- msg.setOnPutFileUpdateListener(cb);
-
- return startPutFileStream(path,msg);
- }
-
- /**
- * Used to push a stream of putfile RPC's containing binary data from a mobile device to the module.
- * Responses are captured through callback on IProxyListener.
- *
- * @param is - The input stream of byte data that putFileStream will read from.
- * @param sdlFileName - The file reference name used by the putFile RPC.
- * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file.
- * A value greater than zero is used for resuming partial data chunks.
- * @param fileType - The selected file type -- see the FileType enumeration for details
- * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse.
- * @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned
- * @throws SdlException if an unrecoverable error is encountered
- * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, Boolean, Integer)
- */
- @SuppressWarnings("unused")
- @Deprecated
- public RPCStreamController putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, fileType);
- msg.setCorrelationID(iCorrelationID);
- msg.setPersistentFile(bPersistentFile);
- msg.setSystemFile(bSystemFile);
- msg.setOffset(iOffset);
- msg.setLength(iLength);
-
- return startPutFileStream(is, msg);
- }
-
- /**
- * Used to push a binary stream of file data onto the module from a mobile
- * device. Responses are captured through callback on IProxyListener.
- *
- * @param inputStream The input stream of byte data that will be read from.
- * @param fileName The SDL file reference name used by the RPC.
- * @param offset The data offset in bytes. A value of zero is used to
- * indicate data starting from the beginning of the file and a value greater
- * than zero is used for resuming partial data chunks.
- * @param length The total length of the file being sent.
- * @param fileType The selected file type. See the {@link FileType} enum for
- * details.
- * @param isPersistentFile Indicates if the file is meant to persist between
- * sessions / ignition cycles.
- * @param isSystemFile Indicates if the file is meant to be passed through
- * core to elsewhere in the system.
- * @param correlationId A unique id that correlates each RPCRequest and
- * RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public RPCStreamController putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId) throws SdlException {
- PutFile msg = new PutFile(fileName, fileType);
- msg.setCorrelationID(correlationId);
- msg.setPersistentFile(isPersistentFile);
- msg.setSystemFile(isSystemFile);
- msg.setOffset(offset);
- msg.setLength(length);
- msg.setPayloadProtected(isPayloadProtected);
-
- return startPutFileStream(inputStream, msg);
- }
-
- /**
- *
- * Used to end an existing putFileStream that was previously initiated with any putFileStream method.
- *
- */
- @SuppressWarnings("unused")
- public void endPutFileStream()
- {
- endRPCStream();
- }
-
-
- /**
- * Used to push a binary data onto the SDL module from a mobile device, such as icons and album art. Not supported on first generation SDL vehicles.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sdlFileName -File reference name.
- * @param fileType -Selected file type.
- * @param persistentFile -Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param fileData byte array of data of the file that is to be sent
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void putfile(@NonNull String sdlFileName, @NonNull FileType fileType, Boolean persistentFile, byte[] fileData, Integer correlationID) throws SdlException
- {
- PutFile msg = new PutFile(sdlFileName, fileType);
- msg.setCorrelationID(correlationID);
- msg.setPersistentFile(persistentFile);
- msg.setBulkData(fileData);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Used to delete a file resident on the SDL module in the app's local cache. Not supported on first generation SDL vehicles.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sdlFileName -File reference name.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void deletefile(@NonNull String sdlFileName, Integer correlationID) throws SdlException
- {
- DeleteFile msg = new DeleteFile(sdlFileName);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Requests the current list of resident filenames for the registered app. Not supported on first generation SDL vehicles.
- * Responses are captured through callback on IProxyListener.
- *
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void listfiles(Integer correlationID) throws SdlException
- {
- ListFiles msg = new ListFiles();
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Used to set existing local file on SDL as the app's icon. Not supported on first generation SDL vehicles.
- * Responses are captured through callback on IProxyListener.
- *
- * @param sdlFileName -File reference name.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setappicon(@NonNull String sdlFileName, Integer correlationID) throws SdlException
- {
- SetAppIcon msg = new SetAppIcon(sdlFileName);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Set an alternate display layout. If not sent, default screen for given platform will be shown.
- * Responses are captured through callback on IProxyListener.
- *
- * @param displayLayout -Predefined or dynamically created screen layout.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setdisplaylayout(@NonNull String displayLayout, Integer correlationID) throws SdlException
- {
- SetDisplayLayout msg = new SetDisplayLayout(displayLayout);
- msg.setCorrelationID(correlationID);
-
- sendRPCRequest(msg);
- }
-
- /**
- * Set an alternate display layout. If not sent, default screen for given platform will be shown.
- * Responses are captured through callback on IProxyListener.
- *
- * @param displayLayout -Predefined or dynamically created screen layout.
- * @param dayColorScheme a TemplateColorScheme object representing the colors that will be used for day color scheme
- * @param nightColorScheme a TemplateColorScheme object representing the colors that will be used for night color scheme
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException if an unrecoverable error is encountered
- */
- @SuppressWarnings("unused")
- public void setdisplaylayout(String displayLayout, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, Integer correlationID) throws SdlException
- {
- SetDisplayLayout msg = new SetDisplayLayout(displayLayout);
- msg.setCorrelationID(correlationID);
- msg.setDayColorScheme(dayColorScheme);
- msg.setNightColorScheme(nightColorScheme);
- sendRPCRequest(msg);
- }
-
- /**
- * Gets the SystemCapabilityManager. <br>
- * @return a SystemCapabilityManager object
- */
- public SystemCapabilityManager getSystemCapabilityManager() {
- return _systemCapabilityManager;
- }
-
- @SuppressWarnings("unused")
- public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType) {
- return _systemCapabilityManager != null && _systemCapabilityManager.isCapabilitySupported(systemCapabilityType);
- }
-
- @SuppressWarnings("unused")
- public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener){
- if(_systemCapabilityManager != null){
- _systemCapabilityManager.getCapability(systemCapabilityType, scListener);
- }
- }
-
- @SuppressWarnings("unused")
- public Object getCapability(SystemCapabilityType systemCapabilityType){
- if(_systemCapabilityManager != null ){
- return _systemCapabilityManager.getCapability(systemCapabilityType);
- }else{
- return null;
- }
- }
-
- /**
- * Add a listener to be called whenever a new capability is retrieved
- * @param systemCapabilityType Type of capability desired
- * @param listener callback to execute upon retrieving capability
- */
- public void addOnSystemCapabilityListener(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener listener) {
- if(_systemCapabilityManager != null){
- _systemCapabilityManager.addOnSystemCapabilityListener(systemCapabilityType, listener);
- }
- }
-
- /**
- * Remove an OnSystemCapabilityListener that was previously added
- * @param systemCapabilityType Type of capability
- * @param listener the listener that should be removed
- */
- public boolean removeOnSystemCapabilityListener(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener listener){
- if(_systemCapabilityManager != null){
- return _systemCapabilityManager.removeOnSystemCapabilityListener(systemCapabilityType, listener);
- }
- return false;
- }
-
- /* ******************* END Public Helper Methods *************************/
-
- /**
- * Gets type of transport currently used by this SdlProxy.
- *
- * @return One of TransportType enumeration values.
- *
- * @see TransportType
- */
- @SuppressWarnings("unused")
- public TransportType getCurrentTransportType() throws IllegalStateException {
- if (sdlSession == null) {
- throw new IllegalStateException("Incorrect state of SdlProxyBase: Calling for getCurrentTransportType() while connection is not initialized");
- }
-
- return sdlSession.getCurrentTransportType();
- }
-
- public void setSdlSecurityClassList(List<Class<? extends SdlSecurityBase>> list) {
- _secList = list;
- }
-
- private void setSdlSecurity(SdlSecurityBase sec) {
- if (sdlSession != null)
- {
- sdlSession.setSdlSecurity(sec);
- }
- }
-
- /**
- * Sets the minimum protocol version that will be permitted to connect.
- * If the protocol version of the head unit connected is below this version,
- * the app will disconnect with an EndService protocol message and will not register.
- * @param minimumProtocolVersion
- */
- public void setMinimumProtocolVersion(Version minimumProtocolVersion){
- this.minimumProtocolVersion = minimumProtocolVersion;
- }
-
- /**
- * The minimum RPC version that will be permitted to connect.
- * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent.
- * @param minimumRPCVersion
- */
- public void setMinimumRPCVersion(Version minimumRPCVersion){
- this.minimumRPCVersion = minimumRPCVersion;
- }
-
- @SuppressWarnings("unused")
- public boolean isServiceTypeProtected(SessionType sType) {
- return sdlSession != null && sdlSession.isServiceProtected(sType);
-
- }
-
-
- public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener){
- if(serviceType != null && sdlSession != null && sdlServiceListener != null){
- sdlSession.addServiceListener(serviceType, sdlServiceListener);
- }
- }
-
- public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener){
- if(serviceType != null && sdlSession != null && sdlServiceListener != null){
- sdlSession.removeServiceListener(serviceType, sdlServiceListener);
- }
- }
-
- @SuppressWarnings("unused")
- public VideoStreamingParameters getAcceptedVideoParams(){
- return sdlSession.getAcceptedVideoParams();
- }
-
- public IProxyListenerBase getProxyListener()
- {
- return _proxyListener;
- }
-
- @SuppressWarnings("unused")
- public String getAppName()
- {
- return _applicationName;
- }
-
- @SuppressWarnings("unused")
- public String getNgnAppName()
- {
- return _ngnMediaScreenAppName;
- }
-
- @SuppressWarnings("unused")
- public String getAppID()
- {
- return _appID;
- }
- @SuppressWarnings("unused")
- public DeviceInfo getDeviceInfo()
- {
- return deviceInfo;
- }
- @SuppressWarnings("unused")
- public long getInstanceDT()
- {
- return instanceDateTime;
- }
- @SuppressWarnings("unused")
- public void setConnectionDetails(String sDetails)
- {
- sConnectionDetails = sDetails;
- }
- @SuppressWarnings("unused")
- public String getConnectionDetails()
- {
- return sConnectionDetails;
- }
- //for testing only
- @SuppressWarnings("unused")
- public void setPoliciesURL(String sText)
- {
- sPoliciesURL = sText;
- }
- //for testing only
- public String getPoliciesURL()
- {
- return sPoliciesURL;
- }
-
- /**
- * Tells developer whether or not their app icon has been resumed on core.
- * @return boolean - true if icon was resumed, false if not
- * @throws SdlException if proxy is disposed or app is not registered
- */
- public boolean getIconResumed() throws SdlException {
- // Test if proxy has been disposed
- if (_proxyDisposed) {
- throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED);
- }
-
- // Test SDL availability
- if (!_appInterfaceRegisterd) {
- throw new SdlException("SDL is not connected. Unable to determine if app icon was resumed.", SdlExceptionCause.SDL_UNAVAILABLE);
- }
- return _iconResumed;
- }
-
- /**
- * Method to retrieve the RegisterAppInterface Response message that was sent back from the
- * module. It contains various attributes about the connected module and can be used to adapt
- * to different module types and their supported features.
- *
- * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet
- * registered with the module.
- */
- public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){
- return this.raiResponse;
- }
-
- /**
- * Get the current OnHMIStatus
- * @return OnHMIStatus object represents the current OnHMIStatus
- */
- public OnHMIStatus getCurrentHMIStatus(){
- return lastHmiStatus;
- }
-
- /**
- * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC
- * service from the module. For example, this should be used to login to a user account.
- * @return the string representation of the auth token
- */
- public String getAuthToken(){
- return this.authToken;
- }
-
- /**
- * VideoStreamingManager houses all the elements needed to create a scoped, streaming manager for video projection. It is only a private, instance
- * dependant class at the moment until it can become public. Once the class is public and API defined, it will be moved into the SdlSession class
- */
- @TargetApi(19)
- private class VideoStreamingManager implements ISdlServiceListener{
- Context context;
- ISdl internalInterface;
- volatile VirtualDisplayEncoder encoder;
- private Class<? extends SdlRemoteDisplay> remoteDisplayClass = null;
- SdlRemoteDisplay remoteDisplay;
- IVideoStreamListener streamListener;
- float[] touchScalar = {1.0f,1.0f}; //x, y
- private HapticInterfaceManager hapticManager;
- SdlMotionEvent sdlMotionEvent = null;
- VideoStreamingParameters videoStreamingParameters;
-
- public VideoStreamingManager(Context context,ISdl iSdl){
- this.context = context;
- this.internalInterface = iSdl;
- encoder = new VirtualDisplayEncoder();
- internalInterface.addServiceListener(SessionType.NAV,this);
- //Take care of the touch events
- internalInterface.addOnRPCNotificationListener(FunctionID.ON_TOUCH_EVENT, new OnRPCNotificationListener() {
- @Override
- public void onNotified(RPCNotification notification) {
- if (notification != null && remoteDisplay != null) {
- List<MotionEvent> events = convertTouchEvent((OnTouchEvent) notification);
- if (events != null && !events.isEmpty()) {
- for (MotionEvent ev : events) {
- remoteDisplay.handleMotionEvent(ev);
- }
- }
- }
- }
- });
- }
-
- /**
- * Starts the video service, caches the supplied params and prepares for the stream to start.
- * @param remoteDisplayClass the extension of SdlRemoteDisplay that will be streamed
- * @param parameters desired video streaming params
- * @param encrypted if the service is to be encrypted or not
- */
- public void startVideoStreaming(Class<? extends SdlRemoteDisplay> remoteDisplayClass, VideoStreamingParameters parameters, boolean encrypted){
- this.remoteDisplayClass = remoteDisplayClass;
- this.videoStreamingParameters = parameters;
- //Make sure the service is started, allows multi transports to connect and register without timing out
- internalInterface.startVideoService(parameters, encrypted);
- //After this, look to the
- }
-
- /**
- * The video service should already be started at this point. Once called, it will start
- * the encoders and fire up the remote display supplied by the user
- * @param parameters
- * @param encrypted
- */
- private void startStream(VideoStreamingParameters parameters, boolean encrypted){
- //Start the service first
- //streamListener = startVideoStream(encrypted,parameters);d
- streamListener = sdlSession.startVideoStream();
- if(streamListener == null){
- Log.e(TAG, "Error starting video service");
- return;
- }
- VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING);
- if(capability != null && capability.getIsHapticSpatialDataSupported()){
- hapticManager = new HapticInterfaceManager(internalInterface);
- }
-
- try {
- encoder.init(context, streamListener, parameters);
- //We are all set so we can start streaming at at this point
- encoder.start();
- //Encoder should be up and running
- createRemoteDisplay(encoder.getVirtualDisplay());
- } catch (Exception e) {
- e.printStackTrace();
- }
- Log.d(TAG, parameters.toString());
- }
-
- public void stopStreaming(){
- if(remoteDisplay!=null){
- remoteDisplay.stop();
- remoteDisplay = null;
- }
- if(encoder!=null){
- encoder.shutDown();
- }
- if(internalInterface!=null){
- internalInterface.stopVideoService();
- }
- }
-
- public void dispose(){
- stopStreaming();
- internalInterface.removeServiceListener(SessionType.NAV,this);
- }
-
- private void createRemoteDisplay(final Display disp){
- try{
- if (disp == null){
- return;
- }
-
- // Dismiss the current presentation if the display has changed.
- if (remoteDisplay != null && remoteDisplay.getDisplay() != disp) {
- remoteDisplay.dismissPresentation();
- }
-
- FutureTask<Boolean> fTask = new FutureTask<Boolean>( new SdlRemoteDisplay.Creator(context, disp, remoteDisplay, remoteDisplayClass, new SdlRemoteDisplay.Callback(){
- @Override
- public void onCreated(final SdlRemoteDisplay remoteDisplay) {
- //Remote display has been created.
- //Now is a good time to do parsing for spatial data
- SdlProxyBase.VideoStreamingManager.this.remoteDisplay = remoteDisplay;
- if(hapticManager != null) {
- remoteDisplay.getMainView().post(new Runnable() {
- @Override
- public void run() {
- hapticManager.refreshHapticData(remoteDisplay.getMainView());
- }
- });
- }
- //Get touch scalars
- ImageResolution resolution = null;
- if(protocolVersion!= null && protocolVersion.getMajor()>=5){ //At this point we should already have the capability
- VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING);
- if (capability != null) {
- resolution = capability.getPreferredResolution();
- }
- }
-
- if(resolution == null){ //Either the protocol version is too low to access video streaming caps, or they were null
- DisplayCapabilities dispCap = (DisplayCapabilities) internalInterface.getCapability(SystemCapabilityType.DISPLAY);
- if (dispCap != null) {
- resolution = (dispCap.getScreenParams().getImageResolution());
- }
- }
-
- if(resolution != null){
- DisplayMetrics displayMetrics = new DisplayMetrics();
- disp.getMetrics(displayMetrics);
- touchScalar[0] = ((float)displayMetrics.widthPixels) / resolution.getResolutionWidth();
- touchScalar[1] = ((float)displayMetrics.heightPixels) / resolution.getResolutionHeight();
- }
-
- }
-
- @Override
- public void onInvalidated(final SdlRemoteDisplay remoteDisplay) {
- //Our view has been invalidated
- //A good time to refresh spatial data
- if(hapticManager != null) {
- remoteDisplay.getMainView().post(new Runnable() {
- @Override
- public void run() {
- hapticManager.refreshHapticData(remoteDisplay.getMainView());
- }
- });
- }
- }
- } ));
- Thread showPresentation = new Thread(fTask);
-
- showPresentation.start();
- } catch (Exception ex) {
- Log.e(TAG, "Unable to create Virtual Display.");
- }
- }
-
- @Override
- public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) {
- if(SessionType.NAV.equals(type) && session != null ){
- DebugTool.logInfo("Video service has been started. Starting video stream from proxy");
- if(session.getAcceptedVideoParams() != null){
- videoStreamingParameters = session.getAcceptedVideoParams();
- }
- startStream(videoStreamingParameters, isEncrypted);
- }
- }
-
- @Override
- public void onServiceEnded(SdlSession session, SessionType type) {
- if(SessionType.NAV.equals(type)){
- if(remoteDisplay!=null){
- stopStreaming();
- }
- }
- }
-
- @Override
- public void onServiceError(SdlSession session, SessionType type, String reason) {
-
- }
-
- private List<MotionEvent> convertTouchEvent(OnTouchEvent onTouchEvent) {
- List<MotionEvent> motionEventList = new ArrayList<MotionEvent>();
-
- List<TouchEvent> touchEventList = onTouchEvent.getEvent();
- if (touchEventList == null || touchEventList.size() == 0) return null;
-
- TouchType touchType = onTouchEvent.getType();
- if (touchType == null) {
- return null;
- }
-
- if (sdlMotionEvent == null) {
- if (touchType == TouchType.BEGIN) {
- sdlMotionEvent = new SdlMotionEvent();
- } else {
- return null;
- }
- }
-
- SdlMotionEvent.Pointer pointer;
- MotionEvent motionEvent;
-
- for (TouchEvent touchEvent : touchEventList) {
- if (touchEvent == null || touchEvent.getId() == null) {
- continue;
- }
-
- List<TouchCoord> touchCoordList = touchEvent.getTouchCoordinates();
- if (touchCoordList == null || touchCoordList.size() == 0) {
- continue;
- }
-
- TouchCoord touchCoord = touchCoordList.get(touchCoordList.size() - 1);
- if (touchCoord == null) {
- continue;
- }
-
- int motionEventAction = sdlMotionEvent.getMotionEventAction(touchType, touchEvent);
- long downTime = sdlMotionEvent.downTime;
- long eventTime = sdlMotionEvent.eventTime;
- pointer = sdlMotionEvent.getPointerById(touchEvent.getId());
- if (pointer != null) {
- pointer.setCoords(touchCoord.getX() * touchScalar[0], touchCoord.getY() * touchScalar[1]);
- }
-
- MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[sdlMotionEvent.pointers.size()];
- MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[sdlMotionEvent.pointers.size()];
-
- for (int i = 0; i < sdlMotionEvent.pointers.size(); i++) {
- pointerProperties[i] = new MotionEvent.PointerProperties();
- pointerProperties[i].id = sdlMotionEvent.getPointerByIndex(i).id;
- pointerProperties[i].toolType = MotionEvent.TOOL_TYPE_FINGER;
-
- pointerCoords[i] = new MotionEvent.PointerCoords();
- pointerCoords[i].x = sdlMotionEvent.getPointerByIndex(i).x;
- pointerCoords[i].y = sdlMotionEvent.getPointerByIndex(i).y;
- pointerCoords[i].orientation = 0;
- pointerCoords[i].pressure = 1.0f;
- pointerCoords[i].size = 1;
- }
-
- motionEvent = MotionEvent.obtain(downTime, eventTime, motionEventAction,
- sdlMotionEvent.pointers.size(), pointerProperties, pointerCoords, 0, 0, 1,
- 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
- motionEventList.add(motionEvent);
-
- if (motionEventAction == MotionEvent.ACTION_UP || motionEventAction == MotionEvent.ACTION_CANCEL) {
- //If the motion event should be finished we should clear our reference
- sdlMotionEvent.pointers.clear();
- sdlMotionEvent = null;
- break;
- } else if ((motionEventAction & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
- sdlMotionEvent.removePointerById(touchEvent.getId());
- }
- }
-
- return motionEventList;
- }
- }
-
- /**
- * Keeps track of the current motion event for VPM
- */
- private static class SdlMotionEvent {
- class Pointer {
- int id;
- float x;
- float y;
-
- Pointer(int id) {
- this.id = id;
- this.x = 0.0f;
- this.y = 0.0f;
- }
-
- void setCoords(float x, float y) {
- this.x = x;
- this.y = y;
- }
- }
-
- private CopyOnWriteArrayList<Pointer> pointers = new CopyOnWriteArrayList<>();
- private long downTime;
- private long downTimeOnHMI;
- private long eventTime;
-
- SdlMotionEvent() {
- downTimeOnHMI = 0;
- }
-
- /**
- * Handles the SDL Touch Event to keep track of pointer status and returns the appropriate
- * Android MotionEvent according to this events status
- *
- * @param touchType The SDL TouchType that was received from the module
- * @param touchEvent The SDL TouchEvent that was received from the module
- * @return the correct native Android MotionEvent action to dispatch
- */
- synchronized int getMotionEventAction(TouchType touchType, TouchEvent touchEvent) {
- eventTime = 0;
- int motionEventAction = -1;
- switch (touchType) {
- case BEGIN:
- if (pointers.size() == 0) {
- //The motion event has just begun
- motionEventAction = MotionEvent.ACTION_DOWN;
- downTime = SystemClock.uptimeMillis();
- downTimeOnHMI = touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1);
- eventTime = downTime;
- } else {
- motionEventAction = MotionEvent.ACTION_POINTER_DOWN | pointers.size() << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
- }
- pointers.add(new Pointer(touchEvent.getId()));
- break;
- case MOVE:
- motionEventAction = MotionEvent.ACTION_MOVE;
- eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
- break;
- case END:
- if(pointers.size() <= 1){
- //The motion event has just ended
- motionEventAction = MotionEvent.ACTION_UP;
- } else {
- int pointerIndex = pointers.indexOf(getPointerById(touchEvent.getId()));
- if (pointerIndex != -1) {
- motionEventAction = MotionEvent.ACTION_POINTER_UP | pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- } else {
- motionEventAction = MotionEvent.ACTION_UP;
- }
- }
- eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
- break;
- case CANCEL:
- //Assuming this cancels the entire event
- motionEventAction = MotionEvent.ACTION_CANCEL;
- eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
- break;
- default:
- break;
- }
- return motionEventAction;
- }
-
- Pointer getPointerById(int id) {
- if (pointers != null && !pointers.isEmpty()) {
- for (Pointer pointer : pointers) {
- if (pointer.id == id) {
- return pointer;
- }
- }
- }
- return null;
- }
-
- Pointer getPointerByIndex(int index) {
- return pointers.get(index);
- }
-
- void removePointerById(int id) {
- pointers.remove(getPointerById(id));
- }
- }
-
-} // end-class
+/* + * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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.proxy; + +import android.annotation.TargetApi; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.SystemClock; +import android.support.annotation.NonNull; +import android.telephony.TelephonyManager; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.SparseArray; +import android.view.Display; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.Surface; + +import com.smartdevicelink.BuildConfig; +import com.smartdevicelink.Dispatcher.IDispatchingStrategy; +import com.smartdevicelink.Dispatcher.ProxyMessageDispatcher; +import com.smartdevicelink.SdlConnection.ISdlConnectionListener; +import com.smartdevicelink.SdlConnection.SdlConnection; +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.SdlConnection.SdlSession2; +import com.smartdevicelink.encoder.VirtualDisplayEncoder; +import com.smartdevicelink.exception.SdlException; +import com.smartdevicelink.exception.SdlExceptionCause; +import com.smartdevicelink.haptic.HapticInterfaceManager; +import com.smartdevicelink.managers.lifecycle.RpcConverter; +import com.smartdevicelink.marshal.JsonRPCMarshaller; +import com.smartdevicelink.protocol.ProtocolMessage; +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.protocol.enums.MessageType; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.protocol.heartbeat.HeartbeatMonitor; +import com.smartdevicelink.proxy.LockScreenManager.OnLockScreenIconDownloadedListener; +import com.smartdevicelink.proxy.callbacks.InternalProxyMessage; +import com.smartdevicelink.proxy.callbacks.OnError; +import com.smartdevicelink.proxy.callbacks.OnProxyClosed; +import com.smartdevicelink.proxy.callbacks.OnServiceEnded; +import com.smartdevicelink.proxy.callbacks.OnServiceNACKed; +import com.smartdevicelink.proxy.interfaces.IAudioStreamListener; +import com.smartdevicelink.proxy.interfaces.IProxyListenerBase; +import com.smartdevicelink.proxy.interfaces.IPutFileResponseListener; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; +import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener; +import com.smartdevicelink.proxy.rpc.*; +import com.smartdevicelink.proxy.rpc.enums.AppHMIType; +import com.smartdevicelink.proxy.rpc.enums.AudioStreamingState; +import com.smartdevicelink.proxy.rpc.enums.AudioType; +import com.smartdevicelink.proxy.rpc.enums.BitsPerSample; +import com.smartdevicelink.proxy.rpc.enums.ButtonName; +import com.smartdevicelink.proxy.rpc.enums.DriverDistractionState; +import com.smartdevicelink.proxy.rpc.enums.FileType; +import com.smartdevicelink.proxy.rpc.enums.GlobalProperty; +import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.ImageType; +import com.smartdevicelink.proxy.rpc.enums.InteractionMode; +import com.smartdevicelink.proxy.rpc.enums.Language; +import com.smartdevicelink.proxy.rpc.enums.PrerecordedSpeech; +import com.smartdevicelink.proxy.rpc.enums.RequestType; +import com.smartdevicelink.proxy.rpc.enums.Result; +import com.smartdevicelink.proxy.rpc.enums.SamplingRate; +import com.smartdevicelink.proxy.rpc.enums.SdlConnectionState; +import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; +import com.smartdevicelink.proxy.rpc.enums.SdlInterfaceAvailability; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.proxy.rpc.enums.TextAlignment; +import com.smartdevicelink.proxy.rpc.enums.TouchType; +import com.smartdevicelink.proxy.rpc.enums.UpdateMode; +import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; +import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; +import com.smartdevicelink.security.SdlSecurityBase; +import com.smartdevicelink.streaming.StreamRPCPacketizer; +import com.smartdevicelink.streaming.audio.AudioStreamingCodec; +import com.smartdevicelink.streaming.audio.AudioStreamingParams; +import com.smartdevicelink.streaming.video.SdlRemoteDisplay; +import com.smartdevicelink.streaming.video.VideoStreamingParameters; +import com.smartdevicelink.trace.SdlTrace; +import com.smartdevicelink.trace.TraceDeviceInfo; +import com.smartdevicelink.trace.enums.InterfaceActivityDirection; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.transport.MultiplexTransportConfig; +import com.smartdevicelink.transport.SiphonServer; +import com.smartdevicelink.transport.USBTransportConfig; +import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.CorrelationIdGenerator; +import com.smartdevicelink.util.DebugTool; +import com.smartdevicelink.util.FileUtls; +import com.smartdevicelink.util.Version; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.Callable; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledExecutorService; + + + +@SuppressWarnings({"WeakerAccess", "Convert2Diamond"}) +public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> { + // Used for calls to Android Log class. + public static final String TAG = "SdlProxy"; + private static final String SDL_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; + private static final int PROX_PROT_VER_ONE = 1; + private static final int RESPONSE_WAIT_TIME = 2000; + + public static final com.smartdevicelink.util.Version MAX_SUPPORTED_RPC_VERSION = new com.smartdevicelink.util.Version("6.0.0"); + + private SdlSession sdlSession = null; + private proxyListenerType _proxyListener = null; + + protected Service _appService = null; + private Context _appContext; + private String sPoliciesURL = ""; //for testing only + + // Protected Correlation IDs + private final int REGISTER_APP_INTERFACE_CORRELATION_ID = 65529, + UNREGISTER_APP_INTERFACE_CORRELATION_ID = 65530, + POLICIES_CORRELATION_ID = 65535; + + // Sdl Synchronization Objects + private static final Object CONNECTION_REFERENCE_LOCK = new Object(), + INCOMING_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + OUTGOING_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + INTERNAL_MESSAGE_QUEUE_THREAD_LOCK = new Object(), + ON_UPDATE_LISTENER_LOCK = new Object(), + RPC_LISTENER_LOCK = new Object(), + ON_NOTIFICATION_LISTENER_LOCK = new Object(); + + private final Object APP_INTERFACE_REGISTERED_LOCK = new Object(); + + private int iFileCount = 0; + + private boolean navServiceStartResponseReceived = false; + private boolean navServiceStartResponse = false; + private List<String> navServiceStartRejectedParams = null; + private boolean pcmServiceStartResponseReceived = false; + private boolean pcmServiceStartResponse = false; + @SuppressWarnings("FieldCanBeLocal") + private List<String> pcmServiceStartRejectedParams = null; + private boolean navServiceEndResponseReceived = false; + private boolean navServiceEndResponse = false; + private boolean pcmServiceEndResponseReceived = false; + private boolean pcmServiceEndResponse = false; + private boolean rpcProtectedResponseReceived = false; + private boolean rpcProtectedStartResponse = false; + + // Device Info for logging + private TraceDeviceInfo _traceDeviceInterrogator = null; + + // Declare Queuing Threads + private ProxyMessageDispatcher<ProtocolMessage> _incomingProxyMessageDispatcher; + private ProxyMessageDispatcher<ProtocolMessage> _outgoingProxyMessageDispatcher; + private ProxyMessageDispatcher<InternalProxyMessage> _internalProxyMessageDispatcher; + + // Flag indicating if callbacks should be called from UIThread + private Boolean _callbackToUIThread = false; + // UI Handler + private Handler _mainUIHandler = null; + final int HEARTBEAT_CORRELATION_ID = 65531; + + // SdlProxy Advanced Lifecycle Management + protected Boolean _advancedLifecycleManagementEnabled = false; + // Parameters passed to the constructor from the app to register an app interface + private String _applicationName = null; + private final long instanceDateTime = System.currentTimeMillis(); + private String sConnectionDetails = "N/A"; + private Vector<TTSChunk> _ttsName = null; + private String _ngnMediaScreenAppName = null; + private Boolean _isMediaApp = null; + private Language _sdlLanguageDesired = null; + private Language _hmiDisplayLanguageDesired = null; + private Vector<AppHMIType> _appType = null; + private String _appID = null; + private TemplateColorScheme _dayColorScheme = null; + private TemplateColorScheme _nightColorScheme = null; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) //Need to understand what this is used for + private String _autoActivateIdDesired = null; + private String _lastHashID = null; + private SdlMsgVersion _sdlMsgVersionRequest = null; + private Vector<String> _vrSynonyms = null; + private boolean _bAppResumeEnabled = false; + private OnSystemRequest lockScreenIconRequest = null; + private TelephonyManager telephonyManager = null; + private DeviceInfo deviceInfo = null; + + /** + * Contains current configuration for the transport that was selected during + * construction of this object + */ + private BaseTransportConfig _transportConfig = null; + // Proxy State Variables + protected Boolean _appInterfaceRegisterd = false; + protected Boolean _preRegisterd = false; + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private Boolean _haveReceivedFirstNonNoneHMILevel = false; + protected Boolean _haveReceivedFirstFocusLevel = false; + protected Boolean _haveReceivedFirstFocusLevelFull = false; + protected Boolean _proxyDisposed = false; + protected SdlConnectionState _sdlConnectionState = null; + protected SdlInterfaceAvailability _sdlIntefaceAvailablity = null; + protected HMILevel _hmiLevel = null; + protected OnHMIStatus lastHmiStatus; + protected AudioStreamingState _audioStreamingState = null; + // Variables set by RegisterAppInterfaceResponse + protected SdlMsgVersion _sdlMsgVersion = null; + protected String _autoActivateIdReturned = null; + protected Language _sdlLanguage = null; + protected Language _hmiDisplayLanguage = null; + protected List<PrerecordedSpeech> _prerecordedSpeech = null; + protected VehicleType _vehicleType = null; + protected String _systemSoftwareVersion = null; + protected List<Integer> _diagModes = null; + protected Boolean firstTimeFull = true; + protected String _proxyVersionInfo = null; + protected Boolean _bResumeSuccess = false; + protected List<Class<? extends SdlSecurityBase>> _secList = null; + protected SystemCapabilityManager _systemCapabilityManager; + protected Boolean _iconResumed = false; + protected RegisterAppInterfaceResponse raiResponse = null; + + private final CopyOnWriteArrayList<IPutFileResponseListener> _putFileListenerList = new CopyOnWriteArrayList<IPutFileResponseListener>(); + + protected com.smartdevicelink.util.Version protocolVersion = new com.smartdevicelink.util.Version(1,0,0); + protected com.smartdevicelink.util.Version rpcSpecVersion; + + protected SparseArray<OnRPCResponseListener> rpcResponseListeners = null; + protected SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>> rpcNotificationListeners = null; + protected SparseArray<CopyOnWriteArrayList<OnRPCRequestListener>> rpcRequestListeners = null; + protected SparseArray<CopyOnWriteArrayList<OnRPCListener>> rpcListeners = null; + + protected VideoStreamingManager manager; //Will move to SdlSession once the class becomes public + + protected String authToken; + + private Version minimumProtocolVersion; + private Version minimumRPCVersion; + + + // Interface broker + private SdlInterfaceBroker _interfaceBroker = null; + //We create an easily passable anonymous class of the interface so that we don't expose the internal interface to developers + private ISdl _internalInterface = new ISdl() { + @Override + public void start() { + try{ + initializeProxy(); + }catch (SdlException e){ + e.printStackTrace(); + } + } + + @Override + public void stop() { + try{ + dispose(); + }catch (SdlException e){ + e.printStackTrace(); + } + } + + @Override + public boolean isConnected() { + return getIsConnected(); + } + + @Override + public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { + SdlProxyBase.this.addServiceListener(serviceType,sdlServiceListener); + } + + @Override + public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { + SdlProxyBase.this.removeServiceListener(serviceType,sdlServiceListener); + } + + @Override + public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { + if(isConnected()){ + sdlSession.setDesiredVideoParams(parameters); + sdlSession.startService(SessionType.NAV,sdlSession.getSessionId(),encrypted); + } + } + + @Override + public void stopVideoService() { + if(isConnected()){ + sdlSession.endService(SessionType.NAV,sdlSession.getSessionId()); + } + } + + @Override public void stopAudioService() { + if(isConnected()){ + sdlSession.endService(SessionType.PCM,sdlSession.getSessionId()); + } + } + + @Override + public void sendRPCRequest(RPCRequest message){ + try { + SdlProxyBase.this.sendRPCRequest(message); + } catch (SdlException e) { + e.printStackTrace(); + } + } + + @Override + public void sendRPC(RPCMessage message) { + try { + SdlProxyBase.this.sendRPC(message); + } catch (SdlException e) { + e.printStackTrace(); + } + } + + @Override + public void sendRequests(List<? extends RPCRequest> rpcs, OnMultipleRequestListener listener) { + try { + SdlProxyBase.this.sendRequests(rpcs, listener); + } catch (SdlException e) { + e.printStackTrace(); + } + } + + @Override + public void sendSequentialRPCs(List<? extends RPCMessage> rpcs, OnMultipleRequestListener listener) { + try{ + SdlProxyBase.this.sendSequentialRequests(rpcs,listener); + }catch (SdlException e ){ + DebugTool.logError("Issue sending sequential RPCs ", e); + } + } + + @Override + public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + SdlProxyBase.this.addOnRPCNotificationListener(notificationId,listener); + } + + @Override + public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { + return SdlProxyBase.this.removeOnRPCNotificationListener(notificationId,listener); + } + + @Override + public void addOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { + SdlProxyBase.this.addOnRPCRequestListener(functionID,listener); + } + + @Override + public boolean removeOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { + return SdlProxyBase.this.removeOnRPCRequestListener(functionID,listener); + } + + @Override + public void addOnRPCListener(FunctionID responseId, OnRPCListener listener) { + SdlProxyBase.this.addOnRPCListener(responseId, listener); + } + + @Override + public boolean removeOnRPCListener(FunctionID responseId, OnRPCListener listener) { + return SdlProxyBase.this.removeOnRPCListener(responseId, listener); + } + + @Override + public Object getCapability(SystemCapabilityType systemCapabilityType){ + return SdlProxyBase.this.getCapability(systemCapabilityType); + } + + @Override + public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { + SdlProxyBase.this.getCapability(systemCapabilityType, scListener); + } + + @Override + public SdlMsgVersion getSdlMsgVersion(){ + try { + return SdlProxyBase.this.getSdlMsgVersion(); + } catch (SdlException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public com.smartdevicelink.util.Version getProtocolVersion() { + return SdlProxyBase.this.protocolVersion; + } + + @Override + public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){ + return SdlProxyBase.this.isCapabilitySupported(systemCapabilityType); + } + + @Override + public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { + SdlProxyBase.this.removeOnSystemCapabilityListener(systemCapabilityType, listener); + } + + @Override + public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { + return SdlProxyBase.this.removeOnSystemCapabilityListener(systemCapabilityType, listener); + } + + @Override + public boolean isTransportForServiceAvailable(SessionType serviceType) { + return SdlProxyBase.this.sdlSession != null + && SdlProxyBase.this.sdlSession.isTransportForServiceAvailable(serviceType); + } + + @Override + public void startAudioService(boolean isEncrypted, AudioStreamingCodec codec, + AudioStreamingParams params) { + if(getIsConnected()){ + SdlProxyBase.this.startAudioStream(isEncrypted, codec, params); + } + } + + @Override + public void startAudioService(boolean encrypted) { + if(isConnected()){ + sdlSession.startService(SessionType.PCM,sdlSession.getSessionId(),encrypted); + } + } + + @Override + public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){ + return SdlProxyBase.this.startVideoStream(isEncrypted, parameters); + } + + @Override + public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, + AudioStreamingParams params) { + return SdlProxyBase.this.startAudioStream(isEncrypted, codec, params); + } + }; + + private void notifyPutFileStreamError(Exception e, String info) + { + for (IPutFileResponseListener _putFileListener : _putFileListenerList) { + _putFileListener.onPutFileStreamError(e, info); + } + } + + private void notifyPutFileStreamResponse(PutFileResponse msg) + { + for (IPutFileResponseListener _putFileListener : _putFileListenerList) { + _putFileListener.onPutFileResponse(msg); + } + } + + public void addPutFileResponseListener(IPutFileResponseListener _putFileListener) + { + _putFileListenerList.addIfAbsent(_putFileListener); + } + + public void remPutFileResponseListener(IPutFileResponseListener _putFileListener) + { + _putFileListenerList.remove(_putFileListener); + } + + // Private Class to Interface with SdlConnection + private class SdlInterfaceBroker implements ISdlConnectionListener { + + @Override + public void onTransportDisconnected(String info) { + // proxyOnTransportDisconnect is called to alert the proxy that a requested + // disconnect has completed + notifyPutFileStreamError(null, info); + + //if (!_advancedLifecycleManagementEnabled) { + // If original model, notify app the proxy is closed so it will delete and reinstanciate + Log.d(TAG, "notifying proxy of closed"); + notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT); + //}// else If ALM, nothing is required to be done here + + } + + @Override + public void onTransportDisconnected(String info, boolean altTransportAvailable, BaseTransportConfig transportConfig) { + notifyPutFileStreamError(null, info); + + if( altTransportAvailable){ + SdlProxyBase.this._transportConfig = transportConfig; + Log.d(TAG, "notifying RPC session ended, but potential primary transport available"); + cycleProxy(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST); + + }else{ + notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT); + } + } + + @Override + public void onTransportError(String info, Exception e) { + DebugTool.logError("Transport failure: " + info, e); + + notifyPutFileStreamError(e, info); + + if (_advancedLifecycleManagementEnabled) { + // Cycle the proxy + if(SdlConnection.isLegacyModeEnabled()){ //FIXME + cycleProxy(SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED); + + }else{ + cycleProxy(SdlDisconnectedReason.TRANSPORT_ERROR); + } + } else { + notifyProxyClosed(info, e, SdlDisconnectedReason.TRANSPORT_ERROR); + } + } + + @Override + public void onProtocolMessageReceived(ProtocolMessage msg) { + + // AudioPathThrough is coming WITH BulkData but WITHOUT JSON Data + // Policy Snapshot is coming WITH BulkData and WITH JSON Data + if ((msg.getData() != null && msg.getData().length > 0) || + (msg.getBulkData() != null && msg.getBulkData().length > 0)) { + queueIncomingMessage(msg); + } + } + + @Override + public void onProtocolSessionStarted(SessionType sessionType, + byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted) { + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStarted"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " ServiceType: " + sessionType.getName()); + updateBroadcastIntent(sendIntent, "COMMENT3", " Encrypted: " + isEncrypted); + sendBroadcastIntent(sendIntent); + + if(sdlSession!= null){ + setProtocolVersion(sdlSession.getProtocolVersion()); + }else{ + setProtocolVersion(new com.smartdevicelink.util.Version(version,0,0)); + } + + + if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1){ + Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion())); + endService(sessionType); + try { + cleanProxy(SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED); + } catch (SdlException e) { + e.printStackTrace(); + } + return; + } + + + if (sessionType.eq(SessionType.RPC)) { + + if (!isEncrypted) + { + if ( (_transportConfig.getHeartBeatTimeout() != Integer.MAX_VALUE) && (version > 2)) + { + HeartbeatMonitor outgoingHeartbeatMonitor = new HeartbeatMonitor(); + outgoingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout()); + sdlSession.setOutgoingHeartbeatMonitor(outgoingHeartbeatMonitor); + + HeartbeatMonitor incomingHeartbeatMonitor = new HeartbeatMonitor(); + incomingHeartbeatMonitor.setInterval(_transportConfig.getHeartBeatTimeout()); + sdlSession.setIncomingHeartbeatMonitor(incomingHeartbeatMonitor); + } + + startRPCProtocolSession(); + } + else + { + RPCProtectedServiceStarted(); + } + } else if (sessionType.eq(SessionType.NAV)) { + NavServiceStarted(); + } else if (sessionType.eq(SessionType.PCM)) { + AudioServiceStarted(); + } else if (sessionType.eq(SessionType.RPC)){ + cycleProxy(SdlDisconnectedReason.RPC_SESSION_ENDED); + } + else if (protocolVersion!= null && protocolVersion.getMajor() > 1) { + //If version is 2 or above then don't need to specify a Session Type + startRPCProtocolSession(); + } //else{} Handle other protocol session types here + + } + + @Override + public void onProtocolSessionStartedNACKed(SessionType sessionType, + byte sessionID, byte version, String correlationID, List<String> rejectedParams) { + OnServiceNACKed message = new OnServiceNACKed(sessionType); + queueInternalMessage(message); + + if (sessionType.eq(SessionType.NAV)) { + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStartedNACKed"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + NavServiceStartedNACK(rejectedParams); + } + else if (sessionType.eq(SessionType.PCM)) { + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionStartedNACKed"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + AudioServiceStartedNACK(rejectedParams); + } + } + + @Override + public void onProtocolSessionEnded(SessionType sessionType, + byte sessionID, String correlationID) { + OnServiceEnded message = new OnServiceEnded(sessionType); + queueInternalMessage(message); + + if (sessionType.eq(SessionType.NAV)) { + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEnded"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " End ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + NavServiceEnded(); + } + else if (sessionType.eq(SessionType.PCM)) { + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEnded"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " End ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + AudioServiceEnded(); + } + } + + @Override + public void onProtocolError(String info, Exception e) { + notifyPutFileStreamError(e, info); + passErrorToProxyListener(info, e); + } + + @Override + public void onHeartbeatTimedOut(byte sessionID) { + final String msg = "Heartbeat timeout"; + DebugTool.logInfo(msg); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onHeartbeatTimedOut"); + updateBroadcastIntent(sendIntent, "COMMENT1", "Heartbeat timeout for SessionID: " + sessionID); + sendBroadcastIntent(sendIntent); + + notifyProxyClosed(msg, new SdlException(msg, SdlExceptionCause.HEARTBEAT_PAST_DUE), SdlDisconnectedReason.HB_TIMEOUT); + + } + + @Override + public void onProtocolSessionEndedNACKed(SessionType sessionType, + byte sessionID, String correlationID) { + if (sessionType.eq(SessionType.NAV)) { + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEndedNACKed"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " End NACK ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + NavServiceEndedNACK(); + } + else if (sessionType.eq(SessionType.PCM)) { + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onProtocolSessionEndedNACKed"); + updateBroadcastIntent(sendIntent, "COMMENT1", "SessionID: " + sessionID); + updateBroadcastIntent(sendIntent, "COMMENT2", " End NACK ServiceType: " + sessionType.getName()); + sendBroadcastIntent(sendIntent); + + AudioServiceEndedNACK(); + } + + } + + public void onProtocolServiceDataACK(SessionType sessionType, final int dataSize, + byte sessionID) { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onServiceDataACK(dataSize); + } + }); + } else { + _proxyListener.onServiceDataACK(dataSize); + } + } + + @Override + public void onAuthTokenReceived(String authToken, byte sessionID) { + SdlProxyBase.this.authToken = authToken; + } + } + + protected SdlProxyBase(){} + + /** + * Used by the SdlManager + * + * @param listener Type of listener for this proxy base. + * @param context Application context. + * @param appName Client application name. + * @param shortAppName Client short application name. + * @param isMediaApp Flag that indicates that client application if media application or not. + * @param languageDesired Desired language. + * @param hmiDisplayLanguageDesired Desired language for HMI. + * @param appType Type of application. + * @param appID Application identifier. + * @param dayColorScheme TemplateColorScheme for the day + * @param nightColorScheme TemplateColorScheme for the night + * @param transportConfig Configuration of transport to be used by underlying connection. + * @param vrSynonyms List of synonyms. + * @param ttsName TTS name. + * @throws SdlException + */ + public SdlProxyBase(proxyListenerType listener, Context context, String appName,String shortAppName, Boolean isMediaApp, Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + BaseTransportConfig transportConfig, Vector<String> vrSynonyms, Vector<TTSChunk> ttsName, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme) throws SdlException { + performBaseCommon(listener, null, true, appName, ttsName, shortAppName, vrSynonyms, isMediaApp, + null, languageDesired, hmiDisplayLanguageDesired, appType, appID, null, dayColorScheme,nightColorScheme, false, false, null, null, transportConfig); + _appContext = context; + } + + /** + * Constructor. + * + * @param listener Type of listener for this proxy base. + * @param sdlProxyConfigurationResources Configuration resources for this proxy. + * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not. + * @param appName Client application name. + * @param ttsName TTS name. + * @param ngnMediaScreenAppName Media Screen Application name. + * @param vrSynonyms List of synonyms. + * @param isMediaApp Flag that indicates that client application if media application or not. + * @param sdlMsgVersion Version of Sdl Message. + * @param languageDesired Desired language. + * @param hmiDisplayLanguageDesired Desired language for HMI. + * @param appType Type of application. + * @param appID Application identifier. + * @param autoActivateID Auto activation identifier. + * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not. + * @param transportConfig Configuration of transport to be used by underlying connection. + * @throws SdlException if there is an unrecoverable error class might throw an exception. + */ + protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion, + Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + String autoActivateID, boolean callbackToUIThread, BaseTransportConfig transportConfig) + throws SdlException { + + performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, + sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, null, null, callbackToUIThread, null, null, null, transportConfig); + } + + @SuppressWarnings("ConstantConditions") + private void performBaseCommon(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion, + Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, + boolean callbackToUIThread, Boolean preRegister, String sHashID, Boolean bAppResumeEnab, + BaseTransportConfig transportConfig) throws SdlException + { + Log.i(TAG, "SDL_LIB_VERSION: " + BuildConfig.VERSION_NAME); + setProtocolVersion(new Version(PROX_PROT_VER_ONE,0,0)); + + if (preRegister != null && preRegister) + { + _appInterfaceRegisterd = preRegister; + _preRegisterd = preRegister; + } + + if (bAppResumeEnab != null && bAppResumeEnab) + { + _bAppResumeEnabled = true; + _lastHashID = sHashID; + } + _interfaceBroker = new SdlInterfaceBroker(); + + _callbackToUIThread = callbackToUIThread; + + if (_callbackToUIThread) { + _mainUIHandler = new Handler(Looper.getMainLooper()); + } + + // Set variables for Advanced Lifecycle Management + _advancedLifecycleManagementEnabled = enableAdvancedLifecycleManagement; + _applicationName = appName; + _ttsName = ttsName; + _ngnMediaScreenAppName = ngnMediaScreenAppName; + _isMediaApp = isMediaApp; + _sdlMsgVersionRequest = sdlMsgVersion; + _vrSynonyms = vrSynonyms; + _sdlLanguageDesired = languageDesired; + _hmiDisplayLanguageDesired = hmiDisplayLanguageDesired; + _appType = appType; + _appID = appID; + _autoActivateIdDesired = autoActivateID; + _dayColorScheme = dayColorScheme; + _nightColorScheme = nightColorScheme; + _transportConfig = transportConfig; + + // Test conditions to invalidate the proxy + if (listener == null) { + throw new IllegalArgumentException("IProxyListener listener must be provided to instantiate SdlProxy object."); + } + if (_advancedLifecycleManagementEnabled) { + /* if (_applicationName == null ) { + throw new IllegalArgumentException("To use SdlProxyALM, an application name, appName, must be provided"); + } + if (_applicationName.length() < 1 || _applicationName.length() > 100) { + throw new IllegalArgumentException("A provided application name, appName, must be between 1 and 100 characters in length."); + }*/ + if (_isMediaApp == null) { + throw new IllegalArgumentException("isMediaApp must not be null when using SdlProxyALM."); + } + } + + _proxyListener = listener; + + // Get information from sdlProxyConfigurationResources + if (sdlProxyConfigurationResources != null) { + telephonyManager = sdlProxyConfigurationResources.getTelephonyManager(); + } + + // Use the telephonyManager to get and log phone info + if (telephonyManager != null) { + // Following is not quite thread-safe (because m_traceLogger could test null twice), + // so we need to fix this, but vulnerability (i.e. two instances of listener) is + // likely harmless. + if (_traceDeviceInterrogator == null) { + _traceDeviceInterrogator = new TraceDeviceInfo(telephonyManager); + } // end-if + + } // end-if + + // Setup Internal ProxyMessage Dispatcher + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure internalProxyMessageDispatcher is null + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + + _internalProxyMessageDispatcher = new ProxyMessageDispatcher<InternalProxyMessage>("INTERNAL_MESSAGE_DISPATCHER", new IDispatchingStrategy<InternalProxyMessage>() { + + @Override + public void dispatch(InternalProxyMessage message) { + dispatchInternalMessage(message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromInternalMessageDispatcher(info, ex); + } + }); + } + + // Setup Incoming ProxyMessage Dispatcher + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure incomingProxyMessageDispatcher is null + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + + _incomingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("INCOMING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchIncomingMessage(message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromIncomingMessageDispatcher(info, ex); + } + }); + } + + // Setup Outgoing ProxyMessage Dispatcher + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + // Ensure outgoingProxyMessageDispatcher is null + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + + _outgoingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("OUTGOING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() { + @Override + public void dispatch(ProtocolMessage message) { + dispatchOutgoingMessage(message); + } + + @Override + public void handleDispatchingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + + @Override + public void handleQueueingError(String info, Exception ex) { + handleErrorsFromOutgoingMessageDispatcher(info, ex); + } + }); + } + + rpcResponseListeners = new SparseArray<OnRPCResponseListener>(); + rpcNotificationListeners = new SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>>(); + rpcRequestListeners = new SparseArray<CopyOnWriteArrayList<OnRPCRequestListener>>(); + rpcListeners = new SparseArray<CopyOnWriteArrayList<OnRPCListener>>(); + + // Initialize the proxy + try { + initializeProxy(); + } catch (SdlException e) { + // Couldn't initialize the proxy + // Dispose threads and then rethrow exception + + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + throw e; + } + + // Trace that ctor has fired + SdlTrace.logProxyEvent("SdlProxy Created, instanceID=" + this.toString(), SDL_LIB_TRACE_KEY); + } + + protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion, + Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, + boolean callbackToUIThread, boolean preRegister, String sHashID, Boolean bEnableResume, BaseTransportConfig transportConfig) + throws SdlException + { + performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, + sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, dayColorScheme, nightColorScheme, callbackToUIThread, preRegister, sHashID, bEnableResume, transportConfig); + } + + /** + * Constructor. + * + * @param listener Type of listener for this proxy base. + * @param sdlProxyConfigurationResources Configuration resources for this proxy. + * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not. + * @param appName Client application name. + * @param ttsName TTS name. + * @param ngnMediaScreenAppName Media Screen Application name. + * @param vrSynonyms List of synonyms. + * @param isMediaApp Flag that indicates that client application if media application or not. + * @param sdlMsgVersion Version of Sdl Message. + * @param languageDesired Desired language. + * @param hmiDisplayLanguageDesired Desired language for HMI. + * @param appType Type of application. + * @param appID Application identifier. + * @param autoActivateID Auto activation identifier. + * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not. + * @param preRegister Flag that indicates that this proxy should be pre-registerd or not. + * @param transportConfig Configuration of transport to be used by underlying connection. + * @throws SdlException if there is an unrecoverable error class might throw an exception. + */ + protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion, + Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + String autoActivateID, boolean callbackToUIThread, boolean preRegister, BaseTransportConfig transportConfig) + throws SdlException + { + performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, + sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, null, null, callbackToUIThread, preRegister, null, null, transportConfig); + } + + /** + * Constructor. + * + * @param listener Type of listener for this proxy base. + * @param sdlProxyConfigurationResources Configuration resources for this proxy. + * @param enableAdvancedLifecycleManagement Flag that ALM should be enabled or not. + * @param appName Client application name. + * @param ttsName TTS name. + * @param ngnMediaScreenAppName Media Screen Application name. + * @param vrSynonyms List of synonyms. + * @param isMediaApp Flag that indicates that client application if media application or not. + * @param sdlMsgVersion Version of Sdl Message. + * @param languageDesired Desired language. + * @param hmiDisplayLanguageDesired Desired language for HMI. + * @param appType Type of application. + * @param appID Application identifier. + * @param autoActivateID Auto activation identifier. + * @param dayColorScheme Day color scheme. + * @param dayColorScheme Night color scheme. + * @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not. + * @param preRegister Flag that indicates that this proxy should be pre-registerd or not. + * @param transportConfig Configuration of transport to be used by underlying connection. + * @throws SdlException if there is an unrecoverable error class might throw an exception. + */ + protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources, + boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion, + Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID, + String autoActivateID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, + boolean callbackToUIThread, boolean preRegister, BaseTransportConfig transportConfig) + throws SdlException + { + performBaseCommon(listener, sdlProxyConfigurationResources, enableAdvancedLifecycleManagement, appName, ttsName, ngnMediaScreenAppName, vrSynonyms, isMediaApp, + sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, dayColorScheme, nightColorScheme, callbackToUIThread, preRegister, null, null, transportConfig); + } + + private Intent createBroadcastIntent() + { + Intent sendIntent = new Intent(); + sendIntent.setAction("com.smartdevicelink.broadcast"); + sendIntent.putExtra("APP_NAME", this._applicationName); + sendIntent.putExtra("APP_ID", this._appID); + sendIntent.putExtra("RPC_NAME", ""); + sendIntent.putExtra("TYPE", ""); + sendIntent.putExtra("SUCCESS", true); + sendIntent.putExtra("CORRID", 0); + sendIntent.putExtra("FUNCTION_NAME", ""); + sendIntent.putExtra("COMMENT1", ""); + sendIntent.putExtra("COMMENT2", ""); + sendIntent.putExtra("COMMENT3", ""); + sendIntent.putExtra("COMMENT4", ""); + sendIntent.putExtra("COMMENT5", ""); + sendIntent.putExtra("COMMENT6", ""); + sendIntent.putExtra("COMMENT7", ""); + sendIntent.putExtra("COMMENT8", ""); + sendIntent.putExtra("COMMENT9", ""); + sendIntent.putExtra("COMMENT10", ""); + sendIntent.putExtra("DATA", ""); + sendIntent.putExtra("SHOW_ON_UI", true); + return sendIntent; + } + private void updateBroadcastIntent(Intent sendIntent, String sKey, String sValue) + { + if (sValue == null) sValue = ""; + sendIntent.putExtra(sKey, sValue); + } + private void updateBroadcastIntent(Intent sendIntent, String sKey, boolean bValue) + { + sendIntent.putExtra(sKey, bValue); + } + private void updateBroadcastIntent(Intent sendIntent, String sKey, int iValue) + { + sendIntent.putExtra(sKey, iValue); + } + + private Service getService() + { + try { + Service myService = null; + if (_proxyListener != null && _proxyListener instanceof Service) { + myService = (Service) _proxyListener; + } else if (_appService != null) { + myService = _appService; + } else if (_appContext != null && _appContext instanceof Service) { + myService = (Service) _appContext; + } + return myService; + } catch (Exception ex){ + return null; + } + } + + private void sendBroadcastIntent(Intent sendIntent) + { + Service myService = null; + if (_proxyListener != null && _proxyListener instanceof Service) + { + myService = (Service) _proxyListener; + } + else if (_appService != null) + { + myService = _appService; + } + Context myContext; + if (myService != null){ + myContext = myService.getApplicationContext(); + } else if (_appContext != null){ + myContext = _appContext; + } + else + { + return; + } + try + { + if (myContext != null) myContext.sendBroadcast(sendIntent); + } + catch(Exception ex) + { + //If the service or context has become unavailable unexpectedly, catch the exception and move on -- no broadcast log will occur. + } + } + + private HttpURLConnection getURLConnection(Headers myHeader, String sURLString, int Timeout, int iContentLen) + { + String sContentType = "application/json"; + int CONNECTION_TIMEOUT = Timeout * 1000; + int READ_TIMEOUT = Timeout * 1000; + boolean bDoOutput = true; + boolean bDoInput = true; + boolean bUsesCaches = false; + String sRequestMeth = "POST"; + + boolean bInstFolRed = false; + String sCharSet = "utf-8"; + int iContentLength = iContentLen; + + URL url; + HttpURLConnection urlConnection; + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "getURLConnection"); + updateBroadcastIntent(sendIntent, "COMMENT1", "Actual Content Length: " + iContentLen); + + if (myHeader != null) + { + //if the header isn't null, use it and replace the hardcoded params + int iTimeout; + int iReadTimeout; + sContentType = myHeader.getContentType(); + iTimeout = myHeader.getConnectTimeout(); + bDoOutput = myHeader.getDoOutput(); + bDoInput = myHeader.getDoInput(); + bUsesCaches = myHeader.getUseCaches(); + sRequestMeth = myHeader.getRequestMethod(); + iReadTimeout = myHeader.getReadTimeout(); + bInstFolRed = myHeader.getInstanceFollowRedirects(); + sCharSet = myHeader.getCharset(); + iContentLength = myHeader.getContentLength(); + CONNECTION_TIMEOUT = iTimeout*1000; + READ_TIMEOUT = iReadTimeout*1000; + updateBroadcastIntent(sendIntent, "COMMENT2", "\nHeader Defined Content Length: " + iContentLength); + } + + try + { + url = new URL(sURLString); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); + urlConnection.setDoOutput(bDoOutput); + urlConnection.setDoInput(bDoInput); + urlConnection.setRequestMethod(sRequestMeth); + urlConnection.setReadTimeout(READ_TIMEOUT); + urlConnection.setInstanceFollowRedirects(bInstFolRed); + urlConnection.setRequestProperty("Content-Type", sContentType); + urlConnection.setRequestProperty("charset", sCharSet); + urlConnection.setRequestProperty("Content-Length", "" + Integer.toString(iContentLength)); + urlConnection.setUseCaches(bUsesCaches); + return urlConnection; + } + catch (Exception e) + { + return null; + } + finally + { + sendBroadcastIntent(sendIntent); + } + } + + + private void sendOnSystemRequestToUrl(OnSystemRequest msg) + { + Intent sendIntent = createBroadcastIntent(); + Intent sendIntent2 = createBroadcastIntent(); + + HttpURLConnection urlConnection = null; + boolean bLegacy = false; + + String sURLString; + if (!getPoliciesURL().equals("")) { + sURLString = sPoliciesURL; + } else { + sURLString = msg.getUrl(); + } + + Integer iTimeout = msg.getTimeout(); + + if (iTimeout == null) + iTimeout = 2000; + + Headers myHeader = msg.getHeader(); + + RequestType requestType = msg.getRequestType(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "sendOnSystemRequestToUrl"); + updateBroadcastIntent(sendIntent, "COMMENT5", "\r\nCloud URL: " + sURLString); + + try + { + if (myHeader == null) { + updateBroadcastIntent(sendIntent, "COMMENT7", "\r\nHTTPRequest Header is null"); + } + + String sBodyString = msg.getBody(); + + JSONObject jsonObjectToSendToServer; + String valid_json = ""; + int length; + if (sBodyString == null) + { + if(requestType == RequestType.HTTP ){ + length = msg.getBulkData().length; + Intent sendIntent3 = createBroadcastIntent(); + updateBroadcastIntent(sendIntent3, "FUNCTION_NAME", "replace"); + updateBroadcastIntent(sendIntent3, "COMMENT1", "Valid Json length before replace: " + length); + sendBroadcastIntent(sendIntent3); + + }else{ + List<String> legacyData = msg.getLegacyData(); + JSONArray jsonArrayOfSdlPPackets = new JSONArray(legacyData); + jsonObjectToSendToServer = new JSONObject(); + jsonObjectToSendToServer.put("data", jsonArrayOfSdlPPackets); + bLegacy = true; + updateBroadcastIntent(sendIntent, "COMMENT6", "\r\nLegacy SystemRequest: true"); + valid_json = jsonObjectToSendToServer.toString().replace("\\", ""); + length = valid_json.getBytes("UTF-8").length; + } + } + else + { + Intent sendIntent3 = createBroadcastIntent(); + updateBroadcastIntent(sendIntent3, "FUNCTION_NAME", "replace"); + updateBroadcastIntent(sendIntent3, "COMMENT1", "Valid Json length before replace: " + sBodyString.getBytes("UTF-8").length); + sendBroadcastIntent(sendIntent3); + valid_json = sBodyString.replace("\\", ""); + length = valid_json.getBytes("UTF-8").length; + } + + urlConnection = getURLConnection(myHeader, sURLString, iTimeout, length); + + if (urlConnection == null) + { + Log.i(TAG, "urlConnection is null, check RPC input parameters"); + updateBroadcastIntent(sendIntent, "COMMENT2", "urlConnection is null, check RPC input parameters"); + return; + } + + DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); + if(requestType == RequestType.HTTP){ + wr.write(msg.getBulkData()); + }else{ + wr.writeBytes(valid_json); + } + + wr.flush(); + wr.close(); + + + long BeforeTime = System.currentTimeMillis(); + long AfterTime = System.currentTimeMillis(); + final long roundtriptime = AfterTime - BeforeTime; + + updateBroadcastIntent(sendIntent, "COMMENT4", " Round trip time: " + roundtriptime); + updateBroadcastIntent(sendIntent, "COMMENT1", "Received response from cloud, response code=" + urlConnection.getResponseCode() + " "); + + int iResponseCode = urlConnection.getResponseCode(); + + if (iResponseCode != HttpURLConnection.HTTP_OK) + { + Log.i(TAG, "Response code not HTTP_OK, returning from sendOnSystemRequestToUrl."); + updateBroadcastIntent(sendIntent, "COMMENT2", "Response code not HTTP_OK, aborting request. "); + return; + } + + InputStream is = urlConnection.getInputStream(); + BufferedReader rd = new BufferedReader(new InputStreamReader(is)); + String line; + StringBuilder response = new StringBuilder(); + while((line = rd.readLine()) != null) + { + response.append(line); + response.append('\r'); + } + rd.close(); + //We've read the body + if(requestType == RequestType.HTTP){ + // Create the SystemRequest RPC to send to module. + PutFile putFile = new PutFile(); + putFile.setFileType(FileType.JSON); + putFile.setCorrelationID(POLICIES_CORRELATION_ID); + putFile.setSdlFileName("response_data"); + putFile.setFileData(response.toString().getBytes("UTF-8")); + putFile.setCRC(response.toString().getBytes()); + updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + response.toString()); + + sendRPCMessagePrivate(putFile); + Log.i("sendSystemRequestToUrl", "sent to sdl"); + + updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.PUT_FILE.toString()); + updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST); + updateBroadcastIntent(sendIntent2, "CORRID", putFile.getCorrelationID()); + + }else{ + Vector<String> cloudDataReceived = new Vector<String>(); + final String dataKey = "data"; + // Convert the response to JSON + JSONObject jsonResponse = new JSONObject(response.toString()); + if(jsonResponse.has(dataKey)){ + if (jsonResponse.get(dataKey) instanceof JSONArray) + { + JSONArray jsonArray = jsonResponse.getJSONArray(dataKey); + for (int i=0; i<jsonArray.length(); i++) + { + if (jsonArray.get(i) instanceof String) + { + cloudDataReceived.add(jsonArray.getString(i)); + //Log.i("sendSystemRequestToUrl", "jsonArray.getString(i): " + jsonArray.getString(i)); + } + } + } + else if (jsonResponse.get(dataKey) instanceof String) + { + cloudDataReceived.add(jsonResponse.getString(dataKey)); + //Log.i("sendSystemRequestToUrl", "jsonResponse.getString(data): " + jsonResponse.getString("data")); + } + } + else + { + DebugTool.logError("sendSystemRequestToUrl: Data in JSON Object neither an array nor a string."); + //Log.i("sendSystemRequestToUrl", "sendSystemRequestToUrl: Data in JSON Object neither an array nor a string."); + return; + } + + String sResponse = cloudDataReceived.toString(); + + if (sResponse.length() > 512) + { + sResponse = sResponse.substring(0, 511); + } + + updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + sResponse); + + // Send new SystemRequest to SDL + SystemRequest mySystemRequest = null; + + if (bLegacy){ + if(cloudDataReceived != null) { + mySystemRequest = new SystemRequest(true); + mySystemRequest.setCorrelationID(getPoliciesReservedCorrelationID()); + mySystemRequest.setLegacyData(cloudDataReceived); + } + }else{ + if (response != null) { + mySystemRequest = new SystemRequest(); + mySystemRequest.setRequestType(RequestType.PROPRIETARY); + mySystemRequest.setCorrelationID(getPoliciesReservedCorrelationID()); + mySystemRequest.setBulkData(response.toString().getBytes()); + } + } + + if (getIsConnected()) + { + sendRPCMessagePrivate(mySystemRequest); + Log.i("sendSystemRequestToUrl", "sent to sdl"); + + updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString()); + updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST); + updateBroadcastIntent(sendIntent2, "CORRID", mySystemRequest.getCorrelationID()); + } + } + } + catch (SdlException e) + { + DebugTool.logError("sendSystemRequestToUrl: Could not get data from JSONObject received.", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " SdlException encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: Could not get data from JSONObject received."+ e); + } + catch (JSONException e) + { + DebugTool.logError("sendSystemRequestToUrl: JSONException: ", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " JSONException encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: JSONException: "+ e); + } + catch (UnsupportedEncodingException e) + { + DebugTool.logError("sendSystemRequestToUrl: Could not encode string.", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " UnsupportedEncodingException encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: Could not encode string."+ e); + } + catch (ProtocolException e) + { + DebugTool.logError("sendSystemRequestToUrl: Could not set request method to post.", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " ProtocolException encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: Could not set request method to post."+ e); + } + catch (MalformedURLException e) + { + DebugTool.logError("sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " MalformedURLException encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server."+ e); + } + catch (IOException e) + { + DebugTool.logError("sendSystemRequestToUrl: IOException: ", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " IOException while sending to cloud: IOException: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: IOException: "+ e); + } + catch (Exception e) + { + DebugTool.logError("sendSystemRequestToUrl: Unexpected Exception: ", e); + updateBroadcastIntent(sendIntent, "COMMENT3", " Exception encountered sendOnSystemRequestToUrl: "+ e); + //Log.i("pt", "sendSystemRequestToUrl: Unexpected Exception: " + e); + } + finally + { + sendBroadcastIntent(sendIntent); + sendBroadcastIntent(sendIntent2); + + if (iFileCount < 10) + iFileCount++; + else + iFileCount = 0; + + if(urlConnection != null) + { + urlConnection.disconnect(); + } + } + } + + private int getPoliciesReservedCorrelationID() { + return POLICIES_CORRELATION_ID; + } + + // Test correlationID + private boolean isCorrelationIDProtected(Integer correlationID) { + return correlationID != null && + (HEARTBEAT_CORRELATION_ID == correlationID + || REGISTER_APP_INTERFACE_CORRELATION_ID == correlationID + || UNREGISTER_APP_INTERFACE_CORRELATION_ID == correlationID + || POLICIES_CORRELATION_ID == correlationID); + + } + + // Protected isConnected method to allow legacy proxy to poll isConnected state + public Boolean getIsConnected() { + return sdlSession != null && sdlSession.getIsConnected(); + } + + + /** + * Returns whether the application is registered in SDL. Note: for testing + * purposes, it's possible that the connection is established, but the + * application is not registered. + * + * @return true if the application is registered in SDL + */ + public Boolean getAppInterfaceRegistered() { + return _appInterfaceRegisterd; + } + + // Function to initialize new proxy connection + public void initializeProxy() throws SdlException { + // Reset all of the flags and state variables + _haveReceivedFirstNonNoneHMILevel = false; + _haveReceivedFirstFocusLevel = false; + _haveReceivedFirstFocusLevelFull = false; + _appInterfaceRegisterd = _preRegisterd; + + _putFileListenerList.clear(); + + _sdlIntefaceAvailablity = SdlInterfaceAvailability.SDL_INTERFACE_UNAVAILABLE; + + //Initialize _systemCapabilityManager here. + _systemCapabilityManager = new SystemCapabilityManager(_internalInterface); + // Setup SdlConnection + synchronized(CONNECTION_REFERENCE_LOCK) { + + //Handle legacy USB connections + if(_transportConfig != null + && TransportType.USB.equals(_transportConfig.getTransportType())){ + //A USB transport config was provided + USBTransportConfig usbTransportConfig = (USBTransportConfig)_transportConfig; + if(usbTransportConfig.getUsbAccessory() == null){ + DebugTool.logInfo("Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service"); + //The accessory was null which means it came from a router service + MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(),_appID); + multiplexTransportConfig.setRequiresHighBandwidth(true); + multiplexTransportConfig.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF); + multiplexTransportConfig.setPrimaryTransports(Collections.singletonList(TransportType.USB)); + multiplexTransportConfig.setSecondaryTransports(new ArrayList<TransportType>()); + _transportConfig = multiplexTransportConfig; + } + } + + if(_transportConfig.getTransportType().equals(TransportType.MULTIPLEX)){ + this.sdlSession = new SdlSession2(_interfaceBroker,(MultiplexTransportConfig)_transportConfig); + }else{ + this.sdlSession = SdlSession.createSession((byte)getProtocolVersion().getMajor(),_interfaceBroker, _transportConfig); + } + } + + synchronized(CONNECTION_REFERENCE_LOCK) { + this.sdlSession.startSession(); + sendTransportBroadcast(); + } + } + /** + * This method will fake the multiplex connection event + */ + @SuppressWarnings("unused") + public void forceOnConnected(){ + synchronized(CONNECTION_REFERENCE_LOCK) { + if (sdlSession != null) { + Log.d(TAG, "Forcing on connected.... might actually need this"); //FIXME + /*if(sdlSession.getSdlConnection()==null){ //There is an issue when switching from v1 to v2+ where the connection is closed. So we restart the session during this call. + try { + sdlSession.startSession(); + } catch (SdlException e) { + e.printStackTrace(); + } + } + sdlSession.getSdlConnection().forceHardwareConnectEvent(TransportType.BLUETOOTH); + */ + } + } + } + + public void sendTransportBroadcast() + { + if (sdlSession == null || _transportConfig == null) return; + + String sTransComment = sdlSession.getBroadcastComment(_transportConfig); + + if (sTransComment == null || sTransComment.equals("")) return; + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "initializeProxy"); + updateBroadcastIntent(sendIntent, "COMMENT1", sTransComment); + sendBroadcastIntent(sendIntent); + } + + + /** + * Public method to enable the siphon transport + */ + @SuppressWarnings("unused") + public void enableSiphonDebug() { + + short enabledPortNumber = SiphonServer.enableSiphonServer(); + String sSiphonPortNumber = "Enabled Siphon Port Number: " + enabledPortNumber; + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "enableSiphonDebug"); + updateBroadcastIntent(sendIntent, "COMMENT1", sSiphonPortNumber); + sendBroadcastIntent(sendIntent); + } + + + + /** + * Public method to disable the Siphon Trace Server + */ + @SuppressWarnings("unused") + public void disableSiphonDebug() { + + short disabledPortNumber = SiphonServer.disableSiphonServer(); + if (disabledPortNumber != -1) { + String sSiphonPortNumber = "Disabled Siphon Port Number: " + disabledPortNumber; + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "disableSiphonDebug"); + updateBroadcastIntent(sendIntent, "COMMENT1", sSiphonPortNumber); + sendBroadcastIntent(sendIntent); + } + } + + + + /** + * Public method to enable the Debug Tool + */ + public static void enableDebugTool() { + DebugTool.enableDebugTool(); + } + + /** + * Public method to disable the Debug Tool + */ + public static void disableDebugTool() { + DebugTool.disableDebugTool(); + } + + /** + * Public method to determine Debug Tool enabled + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public static boolean isDebugEnabled() { + return DebugTool.isDebugEnabled(); + } + + + /** + * Check to see if it a transport is available to perform audio streaming. + * <br><strong>NOTE:</strong> This is only for the audio streaming service, not regular + * streaming of media playback. + * @return true if there is either an audio streaming supported + * transport currently connected or a transport is + * available to connect with. false if there is no + * transport connected to support audio streaming and + * no possibility in the foreseeable future. + */ + public boolean isAudioStreamTransportAvailable(){ + return sdlSession!= null && sdlSession.isTransportForServiceAvailable(SessionType.PCM); + } + + /** + * Check to see if it a transport is available to perform video streaming. + + * @return true if there is either an video streaming supported + * transport currently connected or a transport is + * available to connect with. false if there is no + * transport connected to support video streaming and + * no possibility in the foreseeable future. + */ + public boolean isVideoStreamTransportAvailable(){ + return sdlSession!= null && sdlSession.isTransportForServiceAvailable(SessionType.NAV); + } + + + @SuppressWarnings("unused") + @Deprecated + public void close() throws SdlException { + dispose(); + } + + @SuppressWarnings("UnusedParameters") + private void cleanProxy(SdlDisconnectedReason disconnectedReason) throws SdlException { + if (disconnectedReason == SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED || disconnectedReason == SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED){ + notifyProxyClosed(disconnectedReason.toString(), null, disconnectedReason); + sdlSession.resetSession(); + } + try { + + // ALM Specific Cleanup + if (_advancedLifecycleManagementEnabled) { + _sdlConnectionState = SdlConnectionState.SDL_DISCONNECTED; + + firstTimeFull = true; + + // Should we wait for the interface to be unregistered? + Boolean waitForInterfaceUnregistered = false; + // Unregister app interface + synchronized(CONNECTION_REFERENCE_LOCK) { + if (getIsConnected() && getAppInterfaceRegistered()) { + waitForInterfaceUnregistered = true; + unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID); + } + } + + // Wait for the app interface to be unregistered + if (waitForInterfaceUnregistered) { + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + try { + APP_INTERFACE_REGISTERED_LOCK.wait(3000); + } catch (InterruptedException e) { + // Do nothing + } + } + } + } + + if(rpcResponseListeners != null){ + rpcResponseListeners.clear(); + } + if(rpcNotificationListeners != null){ + rpcNotificationListeners.clear(); + } + + // Clean up SDL Connection + synchronized(CONNECTION_REFERENCE_LOCK) { + if (sdlSession != null) sdlSession.close(); + } + } finally { + SdlTrace.logProxyEvent("SdlProxy cleaned.", SDL_LIB_TRACE_KEY); + } + } + + /** + * Terminates the App's Interface Registration, closes the transport connection, ends the protocol session, and frees any resources used by the proxy. + */ + public void dispose() throws SdlException + { + if (_proxyDisposed) { + throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED); + } + + _proxyDisposed = true; + + SdlTrace.logProxyEvent("Application called dispose() method.", SDL_LIB_TRACE_KEY); + + try{ + // Clean the proxy + cleanProxy(SdlDisconnectedReason.APPLICATION_REQUESTED_DISCONNECT); + + // Close IncomingProxyMessageDispatcher thread + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.dispose(); + _incomingProxyMessageDispatcher = null; + } + } + + // Close OutgoingProxyMessageDispatcher thread + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.dispose(); + _outgoingProxyMessageDispatcher = null; + } + } + + // Close InternalProxyMessageDispatcher thread + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.dispose(); + _internalProxyMessageDispatcher = null; + } + } + + _traceDeviceInterrogator = null; + + rpcResponseListeners = null; + + } finally { + SdlTrace.logProxyEvent("SdlProxy disposed.", SDL_LIB_TRACE_KEY); + } + } // end-method + + + private final static Object CYCLE_LOCK = new Object(); + + private boolean _cycling = false; + + // Method to cycle the proxy, only called in ALM + protected void cycleProxy(SdlDisconnectedReason disconnectedReason) { + if (_cycling) return; + + synchronized(CYCLE_LOCK) + { + try{ + _cycling = true; + cleanProxy(disconnectedReason); + initializeProxy(); + if(!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason) + && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(disconnectedReason)){//We don't want to alert higher if we are just cycling for legacy bluetooth + notifyProxyClosed("Sdl Proxy Cycled", new SdlException("Sdl Proxy Cycled", SdlExceptionCause.SDL_PROXY_CYCLED), disconnectedReason); + } + } + catch (SdlException e) { + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "cycleProxy"); + updateBroadcastIntent(sendIntent, "COMMENT1", "Proxy cycled, exception cause: " + e.getSdlExceptionCause()); + sendBroadcastIntent(sendIntent); + + switch(e.getSdlExceptionCause()) { + case BLUETOOTH_DISABLED: + notifyProxyClosed("Bluetooth is disabled. Bluetooth must be enabled to connect to SDL. Reattempt a connection once Bluetooth is enabled.", + new SdlException("Bluetooth is disabled. Bluetooth must be enabled to connect to SDL. Reattempt a connection once Bluetooth is enabled.", SdlExceptionCause.BLUETOOTH_DISABLED), SdlDisconnectedReason.BLUETOOTH_DISABLED); + break; + case BLUETOOTH_ADAPTER_NULL: + notifyProxyClosed("Cannot locate a Bluetooth adapater. A SDL connection is impossible on this device until a Bluetooth adapter is added.", + new SdlException("Cannot locate a Bluetooth adapater. A SDL connection is impossible on this device until a Bluetooth adapter is added.", SdlExceptionCause.BLUETOOTH_ADAPTER_NULL), SdlDisconnectedReason.BLUETOOTH_ADAPTER_ERROR); + break; + default : + notifyProxyClosed("Cycling the proxy failed.", e, SdlDisconnectedReason.GENERIC_ERROR); + break; + } + } catch (Exception e) { + notifyProxyClosed("Cycling the proxy failed.", e, SdlDisconnectedReason.GENERIC_ERROR); + } + _cycling = false; + } + } + + + + /************* Functions used by the Message Dispatching Queues ****************/ + private void dispatchIncomingMessage(ProtocolMessage message) { + try{ + // Dispatching logic + if (message.getSessionType().equals(SessionType.RPC) + ||message.getSessionType().equals(SessionType.BULK_DATA) ) { + try { + if (protocolVersion!= null && protocolVersion.getMajor() == 1 && message.getVersion() > 1) { + if(sdlSession != null + && sdlSession.getProtocolVersion()!= null + && sdlSession.getProtocolVersion().getMajor() > 1){ + setProtocolVersion(sdlSession.getProtocolVersion()); + }else{ + setProtocolVersion(new Version(message.getVersion(),0,0)); + } + } + + Hashtable<String, Object> hash = new Hashtable<String, Object>(); + if (protocolVersion!= null && protocolVersion.getMajor() > 1) { + Hashtable<String, Object> hashTemp = new Hashtable<String, Object>(); + hashTemp.put(RPCMessage.KEY_CORRELATION_ID, message.getCorrID()); + if (message.getJsonSize() > 0) { + final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData()); + //hashTemp.put(Names.parameters, mhash.get(Names.parameters)); + if (mhash != null) { + hashTemp.put(RPCMessage.KEY_PARAMETERS, mhash); + } + } + + String functionName = FunctionID.getFunctionName(message.getFunctionID()); + if (functionName != null) { + hashTemp.put(RPCMessage.KEY_FUNCTION_NAME, functionName); + } else { + DebugTool.logWarning("Dispatch Incoming Message - function name is null unknown RPC. FunctionId: " + message.getFunctionID()); + return; + } + if (message.getRPCType() == 0x00) { + hash.put(RPCMessage.KEY_REQUEST, hashTemp); + } else if (message.getRPCType() == 0x01) { + hash.put(RPCMessage.KEY_RESPONSE, hashTemp); + } else if (message.getRPCType() == 0x02) { + hash.put(RPCMessage.KEY_NOTIFICATION, hashTemp); + } + if (message.getBulkData() != null) hash.put(RPCStruct.KEY_BULK_DATA, message.getBulkData()); + if (message.getPayloadProtected()) hash.put(RPCStruct.KEY_PROTECTED, true); + } else { + hash = JsonRPCMarshaller.unmarshall(message.getData()); + } + handleRPCMessage(hash); + } catch (final Exception excp) { + DebugTool.logError("Failure handling protocol message: " + excp.toString(), excp); + passErrorToProxyListener("Error handing incoming protocol message.", excp); + } // end-catch + } //else { Handle other protocol message types here} + } catch (final Exception e) { + // Pass error to application through listener + DebugTool.logError("Error handing proxy event.", e); + passErrorToProxyListener("Error handing incoming protocol message.", e); + } + } + + /** + * Get the SDL protocol spec version being used + * @return Version of the protocol spec + */ + public @NonNull Version getProtocolVersion(){ + if(this.protocolVersion == null){ + this.protocolVersion = new Version(1,0,0); + } + return this.protocolVersion; + } + + private void setProtocolVersion(@NonNull Version version) { + this.protocolVersion = version; + } + + public String serializeJSON(RPCMessage msg) + { + try + { + return msg.serializeJSON((byte)this.getProtocolVersion().getMajor()).toString(2); + } + catch (final Exception e) + { + DebugTool.logError("Error handing proxy event.", e); + passErrorToProxyListener("Error serializing message.", e); + return null; + } + } + + private void handleErrorsFromIncomingMessageDispatcher(String info, Exception e) { + passErrorToProxyListener(info, e); + } + + private void dispatchOutgoingMessage(ProtocolMessage message) { + synchronized(CONNECTION_REFERENCE_LOCK) { + if (sdlSession != null) { + sdlSession.sendMessage(message); + } + } + SdlTrace.logProxyEvent("SdlProxy sending Protocol Message: " + message.toString(), SDL_LIB_TRACE_KEY); + } + + private void handleErrorsFromOutgoingMessageDispatcher(String info, Exception e) { + passErrorToProxyListener(info, e); + } + + void dispatchInternalMessage(final InternalProxyMessage message) { + try{ + switch (message.getFunctionName()) { + case InternalProxyMessage.OnProxyError: { + final OnError msg = (OnError) message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onError(msg.getInfo(), msg.getException()); + } + }); + } else { + _proxyListener.onError(msg.getInfo(), msg.getException()); + } + break; + } + case InternalProxyMessage.OnServiceEnded: { + final OnServiceEnded msg = (OnServiceEnded) message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onServiceEnded(msg); + } + }); + } else { + _proxyListener.onServiceEnded(msg); + } + break; + } + case InternalProxyMessage.OnServiceNACKed: { + final OnServiceNACKed msg = (OnServiceNACKed) message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onServiceNACKed(msg); + } + }); + } else { + _proxyListener.onServiceNACKed(msg); + } + + /* *************Start Legacy Specific Call-backs************/ + break; + } + case InternalProxyMessage.OnProxyOpened: + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener) _proxyListener).onProxyOpened(); + } + }); + } else { + ((IProxyListener) _proxyListener).onProxyOpened(); + } + break; + case InternalProxyMessage.OnProxyClosed: { + final OnProxyClosed msg = (OnProxyClosed) message; + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason()); + } + }); + } else { + _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason()); + } + /* ***************End Legacy Specific Call-backs************/ + break; + } + default: + // Diagnostics + SdlTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.", SDL_LIB_TRACE_KEY); + DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy."); + break; + } + + SdlTrace.logProxyEvent("Proxy fired callback: " + message.getFunctionName(), SDL_LIB_TRACE_KEY); + } catch(final Exception e) { + // Pass error to application through listener + DebugTool.logError("Error handing proxy event.", e); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onError("Error handing proxy event.", e); + } + }); + } else { + _proxyListener.onError("Error handing proxy event.", e); + } + } + } + + private void handleErrorsFromInternalMessageDispatcher(String info, Exception e) { + DebugTool.logError(info, e); + // This error cannot be passed to the user, as it indicates an error + // in the communication between the proxy and the application. + + DebugTool.logError("InternalMessageDispatcher failed.", e); + + // Note, this is the only place where the _proxyListener should be referenced asdlhronously, + // with an error on the internalMessageDispatcher, we have no other reliable way of + // communicating with the application. + notifyProxyClosed("Proxy callback dispatcher is down. Proxy instance is invalid.", e, SdlDisconnectedReason.GENERIC_ERROR); + _proxyListener.onError("Proxy callback dispatcher is down. Proxy instance is invalid.", e); + } + /************* END Functions used by the Message Dispatching Queues ****************/ + + // Private sendRPCMessagePrivate method. All RPCMessages are funneled through this method after error checking. + protected void sendRPCMessagePrivate(RPCMessage message) throws SdlException { + try { + SdlTrace.logRPCEvent(InterfaceActivityDirection.Transmit, message, SDL_LIB_TRACE_KEY); + + //FIXME this is temporary until the next major release of the library where OK is removed + if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) message; + if (FunctionID.SUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) + || FunctionID.UNSUBSCRIBE_BUTTON.toString().equals(request.getFunctionName()) + || FunctionID.BUTTON_PRESS.toString().equals(request.getFunctionName())) { + + ButtonName buttonName = (ButtonName) request.getObject(ButtonName.class, SubscribeButton.KEY_BUTTON_NAME); + + + if (rpcSpecVersion != null) { + if (rpcSpecVersion.getMajor() < 5) { + + if (ButtonName.PLAY_PAUSE.equals(buttonName)) { + request.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.OK); + } + } else { //Newer than version 5.0.0 + if (ButtonName.OK.equals(buttonName)) { + RPCRequest request2 = new RPCRequest(request); + request2.setParameters(SubscribeButton.KEY_BUTTON_NAME, ButtonName.PLAY_PAUSE); + request2.setOnRPCResponseListener(request.getOnRPCResponseListener()); + sendRPCMessagePrivate(request2); + return; + } + } + } + + } + } + + message.format(rpcSpecVersion,true); + byte[] msgBytes = JsonRPCMarshaller.marshall(message, (byte)getProtocolVersion().getMajor()); + + ProtocolMessage pm = new ProtocolMessage(); + pm.setData(msgBytes); + pm.setMessageType(MessageType.RPC); + pm.setSessionType(SessionType.RPC); + pm.setFunctionID(FunctionID.getFunctionId(message.getFunctionName())); + pm.setPayloadProtected(message.isPayloadProtected()); + + if (sdlSession != null) { + pm.setSessionID(sdlSession.getSessionId()); + } + + if (message.getBulkData() != null) { + pm.setBulkData(message.getBulkData()); + } + + + if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { // Request Specifics + pm.setRPCType((byte)0x00); + RPCRequest request = (RPCRequest) message; + if (request.getCorrelationID() == null) { + //Log error here + throw new SdlException("CorrelationID cannot be null. RPC: " + request.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT); + } else { + pm.setCorrID(request.getCorrelationID()); + } + if (request.getFunctionName().equalsIgnoreCase(FunctionID.PUT_FILE.name())) { + pm.setPriorityCoefficient(1); + } + } else if (message.getMessageType().equals(RPCMessage.KEY_RESPONSE)) { // Response Specifics + pm.setRPCType((byte)0x01); + RPCResponse response = (RPCResponse) message; + if (response.getCorrelationID() == null) { + //Log error here + throw new SdlException("CorrelationID cannot be null. RPC: " + response.getFunctionName(), SdlExceptionCause.INVALID_ARGUMENT); + } else { + pm.setCorrID(response.getCorrelationID()); + } + } else if (message.getMessageType().equals(RPCMessage.KEY_NOTIFICATION)) { // Notification Specifics + pm.setRPCType((byte)0x02); + } else { + //Log error here + throw new SdlException("RPC message is not a valid type", SdlExceptionCause.INVALID_ARGUMENT); + } + + // Queue this outgoing message + synchronized(OUTGOING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_outgoingProxyMessageDispatcher != null) { + _outgoingProxyMessageDispatcher.queueMessage(pm); + //Since the message is queued we can add it's listener to our list, if it is a Request + if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) message; + OnRPCResponseListener listener = request.getOnRPCResponseListener(); + addOnRPCResponseListener(listener, request.getCorrelationID(), msgBytes.length); + } + } + } + } catch (OutOfMemoryError e) { + SdlTrace.logProxyEvent("OutOfMemory exception while sending message " + message.getFunctionName(), SDL_LIB_TRACE_KEY); + throw new SdlException("OutOfMemory exception while sending message " + message.getFunctionName(), e, SdlExceptionCause.INVALID_ARGUMENT); + } + } + + /** + * Only call this method for a PutFile response. It will cause a class cast exception if not. + * @param correlationId correlation id of the packet being updated + * @param bytesWritten how many bytes were written + * @param totalSize the total size in bytes + */ + @SuppressWarnings("unused") + public void onPacketProgress(int correlationId, long bytesWritten, long totalSize){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + if(rpcResponseListeners !=null + && rpcResponseListeners.indexOfKey(correlationId)>=0){ + ((OnPutFileUpdateListener)rpcResponseListeners.get(correlationId)).onUpdate(correlationId, bytesWritten, totalSize); + } + } + + } + + /** + * Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code, + * <p>Will automatically remove the listener for the list of listeners on completion. + * @param msg The RPCResponse message that was received + * @return if a listener was called or not + */ + @SuppressWarnings("UnusedReturnValue") + private boolean onRPCResponseReceived(RPCResponse msg){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + int correlationId = msg.getCorrelationID(); + if(rpcResponseListeners !=null + && rpcResponseListeners.indexOfKey(correlationId)>=0){ + OnRPCResponseListener listener = rpcResponseListeners.get(correlationId); + if(msg.getSuccess()){ + listener.onResponse(correlationId, msg); + }else{ + listener.onError(correlationId, msg.getResultCode(), msg.getInfo()); + } + rpcResponseListeners.remove(correlationId); + return true; + } + return false; + } + } + +/** + * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id + * @param listener that will get called back when a response is received + * @param correlationId of the RPCRequest that was sent + * @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored. + */ + public void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + if(rpcResponseListeners!=null + && listener !=null){ + if(listener.getListenerType() == OnRPCResponseListener.UPDATE_LISTENER_TYPE_PUT_FILE){ + ((OnPutFileUpdateListener)listener).setTotalSize(totalSize); + } + listener.onStart(correlationId); + rpcResponseListeners.put(correlationId, listener); + } + } + } + + @SuppressWarnings("unused") + public SparseArray<OnRPCResponseListener> getResponseListeners(){ + synchronized(ON_UPDATE_LISTENER_LOCK){ + return this.rpcResponseListeners; + } + } + + @SuppressWarnings("UnusedReturnValue") + public boolean onRPCNotificationReceived(RPCNotification notification){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + CopyOnWriteArrayList<OnRPCNotificationListener> listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName())); + if(listeners!=null && listeners.size()>0) { + for (OnRPCNotificationListener listener : listeners) { + listener.onNotified(notification); + } + return true; + } + return false; + } + } + + @SuppressWarnings("UnusedReturnValue") + public boolean onRPCReceived(RPCMessage message){ + synchronized(RPC_LISTENER_LOCK){ + CopyOnWriteArrayList<OnRPCListener> listeners = rpcListeners.get(FunctionID.getFunctionId(message.getFunctionName())); + if(listeners!=null && listeners.size()>0) { + for (OnRPCListener listener : listeners) { + listener.onReceived(message); + } + return true; + } + return false; + } + } + + @SuppressWarnings("UnusedReturnValue") + public boolean onRPCRequestReceived(RPCRequest request){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + CopyOnWriteArrayList<OnRPCRequestListener> listeners = rpcRequestListeners.get(FunctionID.getFunctionId(request.getFunctionName())); + if(listeners!=null && listeners.size()>0) { + for (OnRPCRequestListener listener : listeners) { + listener.onRequest(request); + } + return true; + } + return false; + } + } + + /** + * This will ad a listener for the specific type of notification. As of now it will only allow + * a single listener per notification function id + * @param notificationId The notification type that this listener is designated for + * @param listener The listener that will be called when a notification of the provided type is received + */ + @SuppressWarnings("unused") + public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(notificationId != null && listener != null){ + if(rpcNotificationListeners.indexOfKey(notificationId.getId()) < 0 ){ + rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList<OnRPCNotificationListener>()); + } + rpcNotificationListeners.get(notificationId.getId()).add(listener); + } + } + } + + /** + * This will add a listener for the specific type of message. As of now it will only allow + * a single listener per request function id + * @param messageId The message type that this listener is designated for + * @param listener The listener that will be called when a request of the provided type is received + */ + @SuppressWarnings("unused") + public void addOnRPCListener(FunctionID messageId, OnRPCListener listener){ + synchronized(RPC_LISTENER_LOCK){ + if(messageId != null && listener != null){ + if(rpcListeners.indexOfKey(messageId.getId()) < 0 ){ + rpcListeners.put(messageId.getId(),new CopyOnWriteArrayList<OnRPCListener>()); + } + rpcListeners.get(messageId.getId()).add(listener); + } + } + } + + public boolean removeOnRPCListener(FunctionID messageId, OnRPCListener listener){ + synchronized(RPC_LISTENER_LOCK){ + if(rpcListeners!= null + && messageId != null + && listener != null + && rpcListeners.indexOfKey(messageId.getId()) >= 0){ + return rpcListeners.get(messageId.getId()).remove(listener); + } + } + return false; + } + + /** + * This will add a listener for the specific type of request. As of now it will only allow + * a single listener per request function id + * @param requestId The request type that this listener is designated for + * @param listener The listener that will be called when a request of the provided type is received + */ + @SuppressWarnings("unused") + public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(requestId != null && listener != null){ + if(rpcRequestListeners.indexOfKey(requestId.getId()) < 0 ){ + rpcRequestListeners.put(requestId.getId(),new CopyOnWriteArrayList<OnRPCRequestListener>()); + } + rpcRequestListeners.get(requestId.getId()).add(listener); + } + } + } + + /** + * This method is no longer valid and will not remove the listener for the supplied notificaiton id + * @param notificationId n/a + * @see #removeOnRPCNotificationListener(FunctionID, OnRPCNotificationListener) + */ + @SuppressWarnings("unused") + @Deprecated + public void removeOnRPCNotificationListener(FunctionID notificationId){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + //rpcNotificationListeners.delete(notificationId.getId()); + } + } + + public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(rpcNotificationListeners!= null + && notificationId != null + && listener != null + && rpcNotificationListeners.indexOfKey(notificationId.getId()) >= 0){ + return rpcNotificationListeners.get(notificationId.getId()).remove(listener); + } + } + return false; + } + + public boolean removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ + synchronized(ON_NOTIFICATION_LISTENER_LOCK){ + if(rpcRequestListeners!= null + && requestId != null + && listener != null + && rpcRequestListeners.indexOfKey(requestId.getId()) >= 0){ + return rpcRequestListeners.get(requestId.getId()).remove(listener); + } + } + return false; + } + + private void processRaiResponse(RegisterAppInterfaceResponse rai) + { + if (rai == null) return; + + this.raiResponse = rai; + + VehicleType vt = rai.getVehicleType(); + if (vt == null) return; + + String make = vt.getMake(); + if (make == null) return; + + if (_secList == null) return; + + SdlSecurityBase sec; + Service svc = getService(); + SdlSecurityBase.setAppService(svc); + if (svc != null && svc.getApplicationContext() != null){ + SdlSecurityBase.setContext(svc.getApplicationContext()); + } else { + SdlSecurityBase.setContext(_appContext); + } + + for (Class<? extends SdlSecurityBase> cls : _secList) + { + try + { + sec = cls.newInstance(); + } + catch (Exception e) + { + continue; + } + + if ( (sec != null) && (sec.getMakeList() != null) ) + { + if (sec.getMakeList().contains(make)) + { + setSdlSecurity(sec); + sec.setAppId(_appID); + if (sdlSession != null) + sec.handleSdlSession(sdlSession); + return; + } + } + } + } + + private void handleRPCMessage(Hashtable<String, Object> hash) { + + if (hash == null){ + DebugTool.logError("handleRPCMessage: hash is null, returning."); + return; + } + + RPCMessage rpcMsg = RpcConverter.convertTableToRpc(hash); + + if (rpcMsg == null){ + DebugTool.logError("handleRPCMessage: rpcMsg is null, returning."); + return; + } + + SdlTrace.logRPCEvent(InterfaceActivityDirection.Receive, rpcMsg, SDL_LIB_TRACE_KEY); + + String functionName = rpcMsg.getFunctionName(); + String messageType = rpcMsg.getMessageType(); + + rpcMsg.format(rpcSpecVersion, true); + + onRPCReceived(rpcMsg); // Should only be called for internal use + + // Requests need to be listened for using the SDLManager's addOnRPCRequestListener method. + // Requests are not supported by IProxyListenerBase + if (messageType.equals(RPCMessage.KEY_REQUEST)) { + + onRPCRequestReceived((RPCRequest) rpcMsg); + + } else if (messageType.equals(RPCMessage.KEY_RESPONSE)) { + // Check to ensure response is not from an internal message (reserved correlation ID) + if (isCorrelationIDProtected((new RPCResponse(hash)).getCorrelationID())) { + // This is a response generated from an internal message, it can be trapped here + // The app should not receive a response for a request it did not send + if ((new RPCResponse(hash)).getCorrelationID() == REGISTER_APP_INTERFACE_CORRELATION_ID + && _advancedLifecycleManagementEnabled + && functionName.equals(FunctionID.REGISTER_APP_INTERFACE.toString())) { + final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash); + msg.format(rpcSpecVersion, true); + if (msg.getSuccess()) { + _appInterfaceRegisterd = true; + } + processRaiResponse(msg); + + //Populate the system capability manager with the RAI response + _systemCapabilityManager.parseRAIResponse(msg); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.REGISTER_APP_INTERFACE.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + sendBroadcastIntent(sendIntent); + + //_autoActivateIdReturned = msg.getAutoActivateID(); + /*Place holder for legacy support*/ _autoActivateIdReturned = "8675309"; + _prerecordedSpeech = msg.getPrerecordedSpeech(); + _sdlLanguage = msg.getLanguage(); + _hmiDisplayLanguage = msg.getHmiDisplayLanguage(); + _sdlMsgVersion = msg.getSdlMsgVersion(); + if(_sdlMsgVersion != null){ + rpcSpecVersion = new com.smartdevicelink.util.Version(_sdlMsgVersion.getMajorVersion(),_sdlMsgVersion.getMinorVersion(), _sdlMsgVersion.getPatchVersion()); + }else{ + rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION; + } + + if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1){ + Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion)); + try { + unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID); + } catch (SdlException e) { + e.printStackTrace(); + } + try { + cleanProxy(SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED); + } catch (SdlException e) { + e.printStackTrace(); + } + return; + } + + _vehicleType = msg.getVehicleType(); + _systemSoftwareVersion = msg.getSystemSoftwareVersion(); + _proxyVersionInfo = BuildConfig.VERSION_NAME; + _iconResumed = msg.getIconResumed(); + + if (_iconResumed == null){ + _iconResumed = false; + } + + if (_bAppResumeEnabled) + { + if ( (_sdlMsgVersion.getMajorVersion() > 2) && (_lastHashID != null) && (msg.getSuccess()) && (msg.getResultCode() != Result.RESUME_FAILED) ) + _bResumeSuccess = true; + else + { + _bResumeSuccess = false; + _lastHashID = null; + } + } + _diagModes = msg.getSupportedDiagModes(); + + String sVersionInfo = "SDL Proxy Version: " + _proxyVersionInfo; + + if (!isDebugEnabled()) + { + enableDebugTool(); + DebugTool.logInfo(sVersionInfo, false); + disableDebugTool(); + } + else + DebugTool.logInfo(sVersionInfo, false); + + sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "RAI_RESPONSE"); + updateBroadcastIntent(sendIntent, "COMMENT1", sVersionInfo); + sendBroadcastIntent(sendIntent); + + // Send onSdlConnected message in ALM + _sdlConnectionState = SdlConnectionState.SDL_CONNECTED; + + // If registerAppInterface failed, exit with OnProxyUnusable + if (!msg.getSuccess()) { + notifyProxyClosed("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: ", + new SdlException("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SdlExceptionCause.SDL_REGISTRATION_ERROR), SdlDisconnectedReason.SDL_REGISTRATION_ERROR); + } + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + }); + } else { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + } else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID + && functionName.equals(FunctionID.ON_ENCODED_SYNC_P_DATA.toString())) { + + Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Notification (Legacy)"); + + final OnSystemRequest msg = new OnSystemRequest(hash); + + // If url is not null, then send to URL + if ( (msg.getUrl() != null) ) + { + // URL has data, attempt to post request to external server + Thread handleOffboardTransmissionThread = new Thread() { + @Override + public void run() { + sendOnSystemRequestToUrl(msg); + } + }; + + handleOffboardTransmissionThread.start(); + } + } + else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID + && functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) { + + Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Response (Legacy)"); + final SystemRequestResponse msg = new SystemRequestResponse(hash); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + sendBroadcastIntent(sendIntent); + } + else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID + && functionName.equals(FunctionID.SYSTEM_REQUEST.toString())) { + final SystemRequestResponse msg = new SystemRequestResponse(hash); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + updateBroadcastIntent(sendIntent, "DATA", serializeJSON(msg)); + sendBroadcastIntent(sendIntent); + } + else if (functionName.equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) { + // UnregisterAppInterface + _appInterfaceRegisterd = false; + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + APP_INTERFACE_REGISTERED_LOCK.notify(); + } + final UnregisterAppInterfaceResponse msg = new UnregisterAppInterfaceResponse(hash); + msg.format(rpcSpecVersion, true); + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + sendBroadcastIntent(sendIntent); + } + return; + } + + if (functionName.equals(FunctionID.REGISTER_APP_INTERFACE.toString())) { + final RegisterAppInterfaceResponse msg = new RegisterAppInterfaceResponse(hash); + msg.format(rpcSpecVersion, true); + if (msg.getSuccess()) { + _appInterfaceRegisterd = true; + } + processRaiResponse(msg); + //Populate the system capability manager with the RAI response + _systemCapabilityManager.parseRAIResponse(msg); + + //_autoActivateIdReturned = msg.getAutoActivateID(); + /*Place holder for legacy support*/ _autoActivateIdReturned = "8675309"; + _prerecordedSpeech = msg.getPrerecordedSpeech(); + _sdlLanguage = msg.getLanguage(); + _hmiDisplayLanguage = msg.getHmiDisplayLanguage(); + _sdlMsgVersion = msg.getSdlMsgVersion(); + rpcSpecVersion = new com.smartdevicelink.util.Version(_sdlMsgVersion.getMajorVersion(),_sdlMsgVersion.getMinorVersion(), _sdlMsgVersion.getPatchVersion()); + _vehicleType = msg.getVehicleType(); + _systemSoftwareVersion = msg.getSystemSoftwareVersion(); + _proxyVersionInfo = BuildConfig.VERSION_NAME; + + if (_bAppResumeEnabled) + { + if ( (_sdlMsgVersion.getMajorVersion() > 2) && (_lastHashID != null) && (msg.getSuccess()) && (msg.getResultCode() != Result.RESUME_FAILED) ) + _bResumeSuccess = true; + else + { + _bResumeSuccess = false; + _lastHashID = null; + } + } + + _diagModes = msg.getSupportedDiagModes(); + + if (!isDebugEnabled()) + { + enableDebugTool(); + DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo); + disableDebugTool(); + } + else + DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo); + + // RegisterAppInterface + if (_advancedLifecycleManagementEnabled) { + + // Send onSdlConnected message in ALM + _sdlConnectionState = SdlConnectionState.SDL_CONNECTED; + + // If registerAppInterface failed, exit with OnProxyUnusable + if (!msg.getSuccess()) { + notifyProxyClosed("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: ", + new SdlException("Unable to register app interface. Review values passed to the SdlProxy constructor. RegisterAppInterface result code: " + msg.getResultCode(), SdlExceptionCause.SDL_REGISTRATION_ERROR), SdlDisconnectedReason.SDL_REGISTRATION_ERROR); + } + } else { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + }); + } else { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + } + } else if (functionName.equals(FunctionID.SPEAK.toString())) { + // SpeakResponse + + final SpeakResponse msg = new SpeakResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSpeakResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSpeakResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.ALERT.toString())) { + // AlertResponse + + final AlertResponse msg = new AlertResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAlertResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onAlertResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SHOW.toString())) { + // ShowResponse + + final ShowResponse msg = new ShowResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onShowResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onShowResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.ADD_COMMAND.toString())) { + // AddCommand + + final AddCommandResponse msg = new AddCommandResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAddCommandResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onAddCommandResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.DELETE_COMMAND.toString())) { + // DeleteCommandResponse + + final DeleteCommandResponse msg = new DeleteCommandResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteCommandResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDeleteCommandResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.ADD_SUB_MENU.toString())) { + // AddSubMenu + + final AddSubMenuResponse msg = new AddSubMenuResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAddSubMenuResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onAddSubMenuResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.DELETE_SUB_MENU.toString())) { + // DeleteSubMenu + + final DeleteSubMenuResponse msg = new DeleteSubMenuResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteSubMenuResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDeleteSubMenuResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SUBSCRIBE_BUTTON.toString())) { + // SubscribeButton + + final SubscribeButtonResponse msg = new SubscribeButtonResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSubscribeButtonResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSubscribeButtonResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UNSUBSCRIBE_BUTTON.toString())) { + // UnsubscribeButton + + final UnsubscribeButtonResponse msg = new UnsubscribeButtonResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUnsubscribeButtonResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onUnsubscribeButtonResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_MEDIA_CLOCK_TIMER.toString())) { + // SetMediaClockTimer + + final SetMediaClockTimerResponse msg = new SetMediaClockTimerResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetMediaClockTimerResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetMediaClockTimerResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) { + + final SystemRequestResponse msg = new SystemRequestResponse(hash); + msg.format(rpcSpecVersion,true); + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + sendBroadcastIntent(sendIntent); + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSystemRequestResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSystemRequestResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.CREATE_INTERACTION_CHOICE_SET.toString())) { + // CreateInteractionChoiceSet + + final CreateInteractionChoiceSetResponse msg = new CreateInteractionChoiceSetResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onCreateInteractionChoiceSetResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onCreateInteractionChoiceSetResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.DELETE_INTERACTION_CHOICE_SET.toString())) { + // DeleteInteractionChoiceSet + + final DeleteInteractionChoiceSetResponse msg = new DeleteInteractionChoiceSetResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteInteractionChoiceSetResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDeleteInteractionChoiceSetResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.PERFORM_INTERACTION.toString())) { + // PerformInteraction + + final PerformInteractionResponse msg = new PerformInteractionResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPerformInteractionResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onPerformInteractionResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_GLOBAL_PROPERTIES.toString())) { + // SetGlobalPropertiesResponse + + final SetGlobalPropertiesResponse msg = new SetGlobalPropertiesResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetGlobalPropertiesResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetGlobalPropertiesResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.RESET_GLOBAL_PROPERTIES.toString())) { + // ResetGlobalProperties + + final ResetGlobalPropertiesResponse msg = new ResetGlobalPropertiesResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onResetGlobalPropertiesResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onResetGlobalPropertiesResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) { + // UnregisterAppInterface + + _appInterfaceRegisterd = false; + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + APP_INTERFACE_REGISTERED_LOCK.notify(); + } + + final UnregisterAppInterfaceResponse msg = new UnregisterAppInterfaceResponse(hash); + msg.format(rpcSpecVersion,true); + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_RESPONSE); + updateBroadcastIntent(sendIntent, "SUCCESS", msg.getSuccess()); + updateBroadcastIntent(sendIntent, "COMMENT1", msg.getInfo()); + updateBroadcastIntent(sendIntent, "COMMENT2", msg.getResultCode().toString()); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + sendBroadcastIntent(sendIntent); + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + }); + } else { + if (_proxyListener instanceof IProxyListener) { + ((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg); + } + onRPCResponseReceived(msg); + } + + notifyProxyClosed("UnregisterAppInterfaceResponse", null, SdlDisconnectedReason.APP_INTERFACE_UNREG); + } else if (functionName.equals(FunctionID.GENERIC_RESPONSE.toString())) { + // GenericResponse (Usually and error) + final GenericResponse msg = new GenericResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGenericResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGenericResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SLIDER.toString())) { + // Slider + final SliderResponse msg = new SliderResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSliderResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSliderResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.PUT_FILE.toString())) { + // PutFile + final PutFileResponse msg = new PutFileResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPutFileResponse(msg); + onRPCResponseReceived(msg); + notifyPutFileStreamResponse(msg); + } + }); + } else { + _proxyListener.onPutFileResponse(msg); + onRPCResponseReceived(msg); + notifyPutFileStreamResponse(msg); + } + } else if (functionName.equals(FunctionID.DELETE_FILE.toString())) { + // DeleteFile + final DeleteFileResponse msg = new DeleteFileResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDeleteFileResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDeleteFileResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.LIST_FILES.toString())) { + // ListFiles + final ListFilesResponse msg = new ListFilesResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onListFilesResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onListFilesResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_APP_ICON.toString())) { + // SetAppIcon + final SetAppIconResponse msg = new SetAppIconResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetAppIconResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetAppIconResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SCROLLABLE_MESSAGE.toString())) { + // ScrollableMessage + final ScrollableMessageResponse msg = new ScrollableMessageResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onScrollableMessageResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onScrollableMessageResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.CHANGE_REGISTRATION.toString())) { + // ChangeLanguageRegistration + final ChangeRegistrationResponse msg = new ChangeRegistrationResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onChangeRegistrationResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onChangeRegistrationResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_DISPLAY_LAYOUT.toString())) { + // SetDisplayLayout + final SetDisplayLayoutResponse msg = new SetDisplayLayoutResponse(hash); + msg.format(rpcSpecVersion,true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetDisplayLayoutResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetDisplayLayoutResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.PERFORM_AUDIO_PASS_THRU.toString())) { + // PerformAudioPassThru + final PerformAudioPassThruResponse msg = new PerformAudioPassThruResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPerformAudioPassThruResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onPerformAudioPassThruResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.END_AUDIO_PASS_THRU.toString())) { + // EndAudioPassThru + final EndAudioPassThruResponse msg = new EndAudioPassThruResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onEndAudioPassThruResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onEndAudioPassThruResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SUBSCRIBE_VEHICLE_DATA.toString())) { + // SubscribeVehicleData + final SubscribeVehicleDataResponse msg = new SubscribeVehicleDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSubscribeVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSubscribeVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UNSUBSCRIBE_VEHICLE_DATA.toString())) { + // UnsubscribeVehicleData + final UnsubscribeVehicleDataResponse msg = new UnsubscribeVehicleDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUnsubscribeVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onUnsubscribeVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_VEHICLE_DATA.toString())) { + // GetVehicleData + final GetVehicleDataResponse msg = new GetVehicleDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SUBSCRIBE_WAY_POINTS.toString())) { + // SubscribeWayPoints + final SubscribeWayPointsResponse msg = new SubscribeWayPointsResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSubscribeWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSubscribeWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UNSUBSCRIBE_WAY_POINTS.toString())) { + // UnsubscribeWayPoints + final UnsubscribeWayPointsResponse msg = new UnsubscribeWayPointsResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUnsubscribeWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onUnsubscribeWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_WAY_POINTS.toString())) { + // GetWayPoints + final GetWayPointsResponse msg = new GetWayPointsResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetWayPointsResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.READ_DID.toString())) { + final ReadDIDResponse msg = new ReadDIDResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onReadDIDResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onReadDIDResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_DTCS.toString())) { + final GetDTCsResponse msg = new GetDTCsResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetDTCsResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetDTCsResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.DIAGNOSTIC_MESSAGE.toString())) { + final DiagnosticMessageResponse msg = new DiagnosticMessageResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDiagnosticMessageResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDiagnosticMessageResponse(msg); + onRPCResponseReceived(msg); + } + } + else if (functionName.equals(FunctionID.SYSTEM_REQUEST.toString())) { + + final SystemRequestResponse msg = new SystemRequestResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSystemRequestResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSystemRequestResponse(msg); + onRPCResponseReceived(msg); + } + } + else if (functionName.equals(FunctionID.SEND_LOCATION.toString())) { + + final SendLocationResponse msg = new SendLocationResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSendLocationResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSendLocationResponse(msg); + onRPCResponseReceived(msg); + } + } + else if (functionName.equals(FunctionID.DIAL_NUMBER.toString())) { + + final DialNumberResponse msg = new DialNumberResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onDialNumberResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onDialNumberResponse(msg); + onRPCResponseReceived(msg); + } + } + else if (functionName.equals(FunctionID.SHOW_CONSTANT_TBT.toString())) { + final ShowConstantTbtResponse msg = new ShowConstantTbtResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onShowConstantTbtResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onShowConstantTbtResponse(msg); + onRPCResponseReceived(msg); + } + } + else if (functionName.equals(FunctionID.ALERT_MANEUVER.toString())) { + final AlertManeuverResponse msg = new AlertManeuverResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onAlertManeuverResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onAlertManeuverResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UPDATE_TURN_LIST.toString())) { + final UpdateTurnListResponse msg = new UpdateTurnListResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUpdateTurnListResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onUpdateTurnListResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_INTERIOR_VEHICLE_DATA.toString())) { + final SetInteriorVehicleDataResponse msg = new SetInteriorVehicleDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetInteriorVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetInteriorVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_INTERIOR_VEHICLE_DATA.toString())) { + final GetInteriorVehicleDataResponse msg = new GetInteriorVehicleDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetInteriorVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetInteriorVehicleDataResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_SYSTEM_CAPABILITY.toString())) { + // GetSystemCapabilityResponse + final GetSystemCapabilityResponse msg = new GetSystemCapabilityResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetSystemCapabilityResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetSystemCapabilityResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.BUTTON_PRESS.toString())) { + final ButtonPressResponse msg = new ButtonPressResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onButtonPressResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onButtonPressResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SEND_HAPTIC_DATA.toString())) { + final SendHapticDataResponse msg = new SendHapticDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSendHapticDataResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSendHapticDataResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SET_CLOUD_APP_PROPERTIES.toString())) { + final SetCloudAppPropertiesResponse msg = new SetCloudAppPropertiesResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onSetCloudAppProperties(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onSetCloudAppProperties(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_CLOUD_APP_PROPERTIES.toString())) { + final GetCloudAppPropertiesResponse msg = new GetCloudAppPropertiesResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetCloudAppProperties(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetCloudAppProperties(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.PUBLISH_APP_SERVICE.toString())) { + final PublishAppServiceResponse msg = new PublishAppServiceResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPublishAppServiceResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onPublishAppServiceResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_APP_SERVICE_DATA.toString())) { + final GetAppServiceDataResponse msg = new GetAppServiceDataResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetAppServiceDataResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetAppServiceDataResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.GET_FILE.toString())) { + final GetFileResponse msg = new GetFileResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onGetFileResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onGetFileResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.PERFORM_APP_SERVICES_INTERACTION.toString())) { + final PerformAppServiceInteractionResponse msg = new PerformAppServiceInteractionResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onPerformAppServiceInteractionResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onPerformAppServiceInteractionResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.CLOSE_APPLICATION.toString())) { + final CloseApplicationResponse msg = new CloseApplicationResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onCloseApplicationResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onCloseApplicationResponse(msg); + onRPCResponseReceived(msg); + } + } else if(functionName.equals(FunctionID.CANCEL_INTERACTION.toString())) { + final CancelInteractionResponse msg = new CancelInteractionResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onCancelInteractionResponse(msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onCancelInteractionResponse(msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.UNPUBLISH_APP_SERVICE.toString())) { + final UnpublishAppServiceResponse msg = new UnpublishAppServiceResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onUnpublishAppServiceResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onUnpublishAppServiceResponse( msg); + onRPCResponseReceived(msg); + } + } else if (functionName.equals(FunctionID.SHOW_APP_MENU.toString())) { + final ShowAppMenuResponse msg = new ShowAppMenuResponse(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onShowAppMenuResponse( msg); + onRPCResponseReceived(msg); + } + }); + } else { + _proxyListener.onShowAppMenuResponse( msg); + onRPCResponseReceived(msg); + } + } else { + if (_sdlMsgVersion != null) { + DebugTool.logError("Unrecognized response Message: " + functionName + + " SDL Message Version = " + _sdlMsgVersion); + } else { + DebugTool.logError("Unrecognized response Message: " + functionName); + } + } // end-if + + } else if (messageType.equals(RPCMessage.KEY_NOTIFICATION)) { + if (functionName.equals(FunctionID.ON_HMI_STATUS.toString())) { + // OnHMIStatus + + final OnHMIStatus msg = new OnHMIStatus(hash); + + //setup lockscreeninfo + if (sdlSession != null) + { + sdlSession.getLockScreenMan().setHMILevel(msg.getHmiLevel()); + } + + msg.setFirstRun(firstTimeFull); + if (msg.getHmiLevel() == HMILevel.HMI_FULL) firstTimeFull = false; + + _hmiLevel = msg.getHmiLevel(); + _audioStreamingState = msg.getAudioStreamingState(); + + msg.format(rpcSpecVersion, true); + lastHmiStatus = msg; + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnHMIStatus(msg); + _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj()); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnHMIStatus(msg); + _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj()); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_COMMAND.toString())) { + // OnCommand + + final OnCommand msg = new OnCommand(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnCommand(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnCommand(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_DRIVER_DISTRACTION.toString())) { + // OnDriverDistration + + final OnDriverDistraction msg = new OnDriverDistraction(hash); + + //setup lockscreeninfo + if (sdlSession != null) + { + DriverDistractionState drDist = msg.getState(); + sdlSession.getLockScreenMan().setDriverDistStatus(drDist == DriverDistractionState.DD_ON); + } + + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnDriverDistraction(msg); + _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj()); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnDriverDistraction(msg); + _proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj()); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_ENCODED_SYNC_P_DATA.toString())) { + + final OnSystemRequest msg = new OnSystemRequest(hash); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.ON_SYSTEM_REQUEST.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_NOTIFICATION); + + // If url is null, then send notification to the app, otherwise, send to URL + if (msg.getUrl() == null) { + updateBroadcastIntent(sendIntent, "COMMENT1", "URL is a null value (received)"); + sendBroadcastIntent(sendIntent); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnSystemRequest(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnSystemRequest(msg); + onRPCNotificationReceived(msg); + } + } else { + updateBroadcastIntent(sendIntent, "COMMENT1", "Sending to cloud: " + msg.getUrl()); + sendBroadcastIntent(sendIntent); + + Log.i("pt", "send to url"); + + if ( (msg.getUrl() != null) ) + { + Thread handleOffboardTransmissionThread = new Thread() { + @Override + public void run() { + sendOnSystemRequestToUrl(msg); + } + }; + + handleOffboardTransmissionThread.start(); + } + } + } else if (functionName.equals(FunctionID.ON_PERMISSIONS_CHANGE.toString())) { + //OnPermissionsChange + + final OnPermissionsChange msg = new OnPermissionsChange(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnPermissionsChange(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnPermissionsChange(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_TBT_CLIENT_STATE.toString())) { + // OnTBTClientState + + final OnTBTClientState msg = new OnTBTClientState(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnTBTClientState(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnTBTClientState(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_BUTTON_PRESS.toString())) { + // OnButtonPress + + final OnButtonPress msg = new OnButtonPress(hash); + msg.format(rpcSpecVersion, true); + final OnButtonPress onButtonPressCompat = (OnButtonPress)handleButtonNotificationFormatting(msg); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnButtonPress(msg); + onRPCNotificationReceived(msg); + if(onButtonPressCompat != null){ + onRPCNotificationReceived(onButtonPressCompat); + _proxyListener.onOnButtonPress(onButtonPressCompat); + } + } + }); + } else { + _proxyListener.onOnButtonPress(msg); + onRPCNotificationReceived(msg); + if(onButtonPressCompat != null){ + onRPCNotificationReceived(onButtonPressCompat); + _proxyListener.onOnButtonPress(onButtonPressCompat); + } + } + } else if (functionName.equals(FunctionID.ON_BUTTON_EVENT.toString())) { + // OnButtonEvent + + final OnButtonEvent msg = new OnButtonEvent(hash); + msg.format(rpcSpecVersion, true); + final OnButtonEvent onButtonEventCompat = (OnButtonEvent)handleButtonNotificationFormatting(msg); + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnButtonEvent(msg); + onRPCNotificationReceived(msg); + if(onButtonEventCompat != null){ + onRPCNotificationReceived(onButtonEventCompat); + _proxyListener.onOnButtonEvent(onButtonEventCompat); + } + } + }); + } else { + _proxyListener.onOnButtonEvent(msg); + onRPCNotificationReceived(msg); + if(onButtonEventCompat != null){ + onRPCNotificationReceived(onButtonEventCompat); + _proxyListener.onOnButtonEvent(onButtonEventCompat); + } + } + } else if (functionName.equals(FunctionID.ON_LANGUAGE_CHANGE.toString())) { + // OnLanguageChange + + final OnLanguageChange msg = new OnLanguageChange(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnLanguageChange(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnLanguageChange(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_HASH_CHANGE.toString())) { + // OnLanguageChange + + final OnHashChange msg = new OnHashChange(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnHashChange(msg); + onRPCNotificationReceived(msg); + if (_bAppResumeEnabled) + { + _lastHashID = msg.getHashID(); + } + } + }); + } else { + _proxyListener.onOnHashChange(msg); + onRPCNotificationReceived(msg); + if (_bAppResumeEnabled) + { + _lastHashID = msg.getHashID(); + } + } + } else if (functionName.equals(FunctionID.ON_SYSTEM_REQUEST.toString())) { + // OnSystemRequest + + final OnSystemRequest msg = new OnSystemRequest(hash); + msg.format(rpcSpecVersion,true); + RequestType requestType = msg.getRequestType(); + if(msg.getUrl() != null) { + if (((requestType == RequestType.PROPRIETARY) && (msg.getFileType() == FileType.JSON)) + || ((requestType == RequestType.HTTP) && (msg.getFileType() == FileType.BINARY))) { + Thread handleOffboardTransmissionThread = new Thread() { + @Override + public void run() { + sendOnSystemRequestToUrl(msg); + } + }; + + handleOffboardTransmissionThread.start(); + } else if (requestType == RequestType.LOCK_SCREEN_ICON_URL) { + //Cache this for when the lockscreen is displayed + lockScreenIconRequest = msg; + } else if (requestType == RequestType.ICON_URL) { + //Download the icon file and send SystemRequest RPC + Thread handleOffBoardTransmissionThread = new Thread() { + @Override + public void run() { + byte[] file = FileUtls.downloadFile(msg.getUrl()); + if (file != null) { + SystemRequest systemRequest = new SystemRequest(); + systemRequest.setFileName(msg.getUrl()); + systemRequest.setBulkData(file); + systemRequest.setRequestType(RequestType.ICON_URL); + try { + sendRPCMessagePrivate(systemRequest); + } catch (SdlException e) { + e.printStackTrace(); + } + } else { + DebugTool.logError("File was null at: " + msg.getUrl()); + } + } + }; + handleOffBoardTransmissionThread.start(); + } + } + + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnSystemRequest(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnSystemRequest(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_AUDIO_PASS_THRU.toString())) { + // OnAudioPassThru + final OnAudioPassThru msg = new OnAudioPassThru(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnAudioPassThru(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnAudioPassThru(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_VEHICLE_DATA.toString())) { + // OnVehicleData + final OnVehicleData msg = new OnVehicleData(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnVehicleData(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnVehicleData(msg); + onRPCNotificationReceived(msg); + } + } + else if (functionName.equals(FunctionID.ON_APP_INTERFACE_UNREGISTERED.toString())) { + // OnAppInterfaceUnregistered + + _appInterfaceRegisterd = false; + synchronized(APP_INTERFACE_REGISTERED_LOCK) { + APP_INTERFACE_REGISTERED_LOCK.notify(); + } + + final OnAppInterfaceUnregistered msg = new OnAppInterfaceUnregistered(hash); + msg.format(rpcSpecVersion,true); + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.ON_APP_INTERFACE_UNREGISTERED.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_NOTIFICATION); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + sendBroadcastIntent(sendIntent); + + if (_advancedLifecycleManagementEnabled) { + // This requires the proxy to be cycled + cycleProxy(SdlDisconnectedReason.convertAppInterfaceUnregisteredReason(msg.getReason())); + } else { + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + ((IProxyListener)_proxyListener).onOnAppInterfaceUnregistered(msg); + onRPCNotificationReceived(msg); + } + notifyProxyClosed("OnAppInterfaceUnregistered", null, SdlDisconnectedReason.APP_INTERFACE_UNREG); + } + } + else if (functionName.equals(FunctionID.ON_KEYBOARD_INPUT.toString())) { + final OnKeyboardInput msg = new OnKeyboardInput(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnKeyboardInput(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnKeyboardInput(msg); + onRPCNotificationReceived(msg); + } + } + else if (functionName.equals(FunctionID.ON_TOUCH_EVENT.toString())) { + final OnTouchEvent msg = new OnTouchEvent(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnTouchEvent(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnTouchEvent(msg); + onRPCNotificationReceived(msg); + } + } + else if (functionName.equals(FunctionID.ON_WAY_POINT_CHANGE.toString())) { + final OnWayPointChange msg = new OnWayPointChange(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnWayPointChange(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnWayPointChange(msg); + onRPCNotificationReceived(msg); + } + } + else if (functionName.equals(FunctionID.ON_INTERIOR_VEHICLE_DATA.toString())) { + final OnInteriorVehicleData msg = new OnInteriorVehicleData(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnInteriorVehicleData(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnInteriorVehicleData(msg); + onRPCNotificationReceived(msg); + } + } + else if (functionName.equals(FunctionID.ON_RC_STATUS.toString())) { + final OnRCStatus msg = new OnRCStatus(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnRCStatus(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnRCStatus(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_APP_SERVICE_DATA.toString())) { + final OnAppServiceData msg = new OnAppServiceData(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnAppServiceData(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnAppServiceData(msg); + onRPCNotificationReceived(msg); + } + } else if (functionName.equals(FunctionID.ON_SYSTEM_CAPABILITY_UPDATED.toString())) { + final OnSystemCapabilityUpdated msg = new OnSystemCapabilityUpdated(hash); + msg.format(rpcSpecVersion, true); + if (_callbackToUIThread) { + // Run in UI thread + _mainUIHandler.post(new Runnable() { + @Override + public void run() { + _proxyListener.onOnSystemCapabilityUpdated(msg); + onRPCNotificationReceived(msg); + } + }); + } else { + _proxyListener.onOnSystemCapabilityUpdated(msg); + onRPCNotificationReceived(msg); + } + } else { + if (_sdlMsgVersion != null) { + DebugTool.logInfo("Unrecognized notification Message: " + functionName + + " connected to SDL using message version: " + _sdlMsgVersion.getMajorVersion() + "." + _sdlMsgVersion.getMinorVersion()); + } else { + DebugTool.logInfo("Unrecognized notification Message: " + functionName); + } + } // end-if + } // end-if notification + + SdlTrace.logProxyEvent("Proxy received RPC Message: " + functionName, SDL_LIB_TRACE_KEY); + } + + //FIXME + /** + * Temporary method to bridge the new PLAY_PAUSE and OKAY button functionality with the old + * OK button name. This should be removed during the next major release + * @param notification + */ + private RPCNotification handleButtonNotificationFormatting(RPCNotification notification){ + if(FunctionID.ON_BUTTON_EVENT.toString().equals(notification.getFunctionName()) + || FunctionID.ON_BUTTON_PRESS.toString().equals(notification.getFunctionName())){ + + ButtonName buttonName = (ButtonName)notification.getObject(ButtonName.class, OnButtonEvent.KEY_BUTTON_NAME); + ButtonName compatBtnName = null; + + if(rpcSpecVersion != null && rpcSpecVersion.getMajor() >= 5){ + if(ButtonName.PLAY_PAUSE.equals(buttonName)){ + compatBtnName = ButtonName.OK; + } + }else{ // rpc spec version is either null or less than 5 + if(ButtonName.OK.equals(buttonName)){ + compatBtnName = ButtonName.PLAY_PAUSE; + } + } + + try { + if (compatBtnName != null) { //There is a button name that needs to be swapped out + RPCNotification notification2; + //The following is done because there is currently no way to make a deep copy + //of an RPC. Since this code will be removed, it's ugliness is borderline acceptable. + if (notification instanceof OnButtonEvent) { + OnButtonEvent onButtonEvent = new OnButtonEvent(); + onButtonEvent.setButtonEventMode(((OnButtonEvent) notification).getButtonEventMode()); + onButtonEvent.setCustomButtonID(((OnButtonEvent) notification).getCustomButtonID()); + notification2 = onButtonEvent; + } else if (notification instanceof OnButtonPress) { + OnButtonPress onButtonPress = new OnButtonPress(); + onButtonPress.setButtonPressMode(((OnButtonPress) notification).getButtonPressMode()); + onButtonPress.setCustomButtonName(((OnButtonPress) notification).getCustomButtonName()); + notification2 = onButtonPress; + } else { + return null; + } + + notification2.setParameters(OnButtonEvent.KEY_BUTTON_NAME, compatBtnName); + return notification2; + } + }catch (Exception e){ + //Should never get here + } + } + return null; + } + + /** + * Get SDL Message Version + * @return SdlMsgVersion + * @throws SdlException + */ + public SdlMsgVersion getSdlMsgVersion() throws SdlException{ + return _sdlMsgVersion; + } + + /** + * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. + * For sending requests asynchronously, use sendRequests <br> + * + * <strong>NOTE: This will override any listeners on individual RPCs</strong> + * + * @param rpcs is the list of RPCMessages being sent + * @param listener listener for updates and completions + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void sendSequentialRequests(final List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) throws SdlException { + if (_proxyDisposed) { + throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED); + } + + SdlTrace.logProxyEvent("Application called sendSequentialRequests", SDL_LIB_TRACE_KEY); + + synchronized(CONNECTION_REFERENCE_LOCK) { + if (!getIsConnected()) { + SdlTrace.logProxyEvent("Application attempted to call sendSequentialRequests without a connected transport.", SDL_LIB_TRACE_KEY); + throw new SdlException("There is no valid connection to SDL. sendSequentialRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE); + } + } + + if (rpcs == null){ + //Log error here + throw new SdlException("You must send some RPCs", SdlExceptionCause.INVALID_ARGUMENT); + } + + // Break out of recursion, we have finished the requests + if (rpcs.size() == 0) { + if(listener != null){ + listener.onFinished(); + } + return; + } + + RPCMessage rpc = rpcs.remove(0); + + // Request Specifics + if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) rpc; + request.setCorrelationID(CorrelationIdGenerator.generateId()); + + final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); + + request.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onResponse(correlationId, response); + } + if (listener != null) { + listener.onResponse(correlationId, response); + listener.onUpdate(rpcs.size()); + + } + try { + // recurse after onResponse + sendSequentialRequests(rpcs, listener); + } catch (SdlException e) { + e.printStackTrace(); + if (listener != null) { + listener.onError(correlationId, Result.GENERIC_ERROR, e.toString()); + } + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onError(correlationId, resultCode, info); + } + if (listener != null) { + listener.onError(correlationId, resultCode, info); + listener.onUpdate(rpcs.size()); + } + try { + // recurse after onError + sendSequentialRequests(rpcs, listener); + } catch (SdlException e) { + e.printStackTrace(); + if (listener != null) { + listener.onError(correlationId, Result.GENERIC_ERROR, e.toString()); + } + } + } + }); + sendRPCMessagePrivate(request); + } else { + // Notifications and Responses + sendRPCMessagePrivate(rpc); + if (listener != null) { + listener.onUpdate(rpcs.size()); + } + // recurse after sending a notification or response as there is no response. + try { + sendSequentialRequests(rpcs, listener); + } catch (SdlException e) { + e.printStackTrace(); + if (listener != null) { + listener.onError(0, Result.GENERIC_ERROR, e.toString()); + } + } + } + + + } + + /** + * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener. + * For sending requests synchronously, use sendSequentialRequests <br> + * + * <strong>NOTE: This will override any listeners on individual RPCs</strong> + * + * @param rpcs is the list of RPCMessages being sent + * @param listener listener for updates and completions + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void sendRequests(List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) throws SdlException { + + if (_proxyDisposed) { + throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED); + } + + SdlTrace.logProxyEvent("Application called sendRequests", SDL_LIB_TRACE_KEY); + + synchronized(CONNECTION_REFERENCE_LOCK) { + if (!getIsConnected()) { + SdlTrace.logProxyEvent("Application attempted to call sendRequests without a connected transport.", SDL_LIB_TRACE_KEY); + throw new SdlException("There is no valid connection to SDL. sendRequests cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE); + } + } + + if (rpcs == null){ + //Log error here + throw new SdlException("You must send some RPCs, the array is null", SdlExceptionCause.INVALID_ARGUMENT); + } + + int arraySize = rpcs.size(); + + if (arraySize == 0) { + throw new SdlException("You must send some RPCs, the array is empty", SdlExceptionCause.INVALID_ARGUMENT); + } + + for (int i = 0; i < arraySize; i++) { + RPCMessage rpc = rpcs.get(i); + // Request Specifics + if (rpc.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) rpc; + final OnRPCResponseListener devOnRPCResponseListener = request.getOnRPCResponseListener(); + request.setCorrelationID(CorrelationIdGenerator.generateId()); + if (listener != null) { + listener.addCorrelationId(request.getCorrelationID()); + request.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onResponse(correlationId, response); + } + if (listener.getSingleRpcResponseListener() != null) { + listener.getSingleRpcResponseListener().onResponse(correlationId, response); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info) { + super.onError(correlationId, resultCode, info); + if (devOnRPCResponseListener != null){ + devOnRPCResponseListener.onError(correlationId, resultCode, info); + } + if (listener.getSingleRpcResponseListener() != null) { + listener.getSingleRpcResponseListener().onError(correlationId, resultCode, info); + } + } + }); + } + sendRPCMessagePrivate(request); + }else { + // Notifications and Responses + sendRPCMessagePrivate(rpc); + if (listener != null){ + listener.onUpdate(rpcs.size()); + if (rpcs.size() == 0){ + listener.onFinished(); + } + } + } + } + } + + public void sendRPC(RPCMessage message) throws SdlException { + if (_proxyDisposed) { + throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED); + } + + // Test if request is null + if (message == null) { + SdlTrace.logProxyEvent("Application called sendRPCRequest method with a null RPCRequest.", SDL_LIB_TRACE_KEY); + throw new IllegalArgumentException("sendRPCRequest cannot be called with a null request."); + } + + SdlTrace.logProxyEvent("Application called sendRPCRequest method for RPCRequest: ." + message.getFunctionName(), SDL_LIB_TRACE_KEY); + + // Test if SdlConnection is null + synchronized(CONNECTION_REFERENCE_LOCK) { + if (!getIsConnected()) { + SdlTrace.logProxyEvent("Application attempted to send and RPCRequest without a connected transport.", SDL_LIB_TRACE_KEY); + throw new SdlException("There is no valid connection to SDL. sendRPCRequest cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE); + } + } + + // Test for illegal correlation ID + if (message.getMessageType().equals(RPCMessage.KEY_REQUEST)) { + RPCRequest request = (RPCRequest) message; + if (isCorrelationIDProtected(request.getCorrelationID())) { + + SdlTrace.logProxyEvent("Application attempted to use the reserved correlation ID, " + request.getCorrelationID(), SDL_LIB_TRACE_KEY); + throw new SdlException("Invalid correlation ID. The correlation ID, " + request.getCorrelationID() + + " , is a reserved correlation ID.", SdlExceptionCause.RESERVED_CORRELATION_ID); + } + } + // Throw exception if RPCRequest is sent when SDL is unavailable + if (!_appInterfaceRegisterd && !message.getFunctionName().equals(FunctionID.REGISTER_APP_INTERFACE.toString())) { + + SdlTrace.logProxyEvent("Application attempted to send an RPCRequest (non-registerAppInterface), before the interface was registerd.", SDL_LIB_TRACE_KEY); + throw new SdlException("SDL is currently unavailable. RPC Requests cannot be sent.", SdlExceptionCause.SDL_UNAVAILABLE); + } + + if (_advancedLifecycleManagementEnabled) { + if (message.getFunctionName().equals(FunctionID.REGISTER_APP_INTERFACE.toString()) + || message.getFunctionName().equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) { + + SdlTrace.logProxyEvent("Application attempted to send a RegisterAppInterface or UnregisterAppInterface while using ALM.", SDL_LIB_TRACE_KEY); + throw new SdlException("The RPCRequest, " + message.getFunctionName() + + ", is un-allowed using the Advanced Lifecycle Management Model.", SdlExceptionCause.INCORRECT_LIFECYCLE_MODEL); + } + } + + sendRPCMessagePrivate(message); + } + + /** + * Takes an RPCRequest and sends it to SDL. Responses are captured through callback on IProxyListener. + * + * @param request is the RPCRequest being sent + * @throws SdlException if an unrecoverable error is encountered + * @deprecated - use sendRPC instead + */ + @Deprecated + public void sendRPCRequest(RPCRequest request) throws SdlException { + sendRPC(request); + } + + protected void notifyProxyClosed(final String info, final Exception e, final SdlDisconnectedReason reason) { + SdlTrace.logProxyEvent("NotifyProxyClose", SDL_LIB_TRACE_KEY); + Log.d(TAG, "notifyProxyClosed: " + info); + OnProxyClosed message = new OnProxyClosed(info, e, reason); + queueInternalMessage(message); + } + + private void passErrorToProxyListener(final String info, final Exception e) { + + OnError message = new OnError(info, e); + queueInternalMessage(message); + } + + private void startRPCProtocolSession() { + + // Set Proxy Lifecyclek Available + if (_advancedLifecycleManagementEnabled) { + + try { + registerAppInterfacePrivate( + _sdlMsgVersionRequest, + _applicationName, + _ttsName, + _ngnMediaScreenAppName, + _vrSynonyms, + _isMediaApp, + _sdlLanguageDesired, + _hmiDisplayLanguageDesired, + _appType, + _appID, + _dayColorScheme, + _nightColorScheme, + REGISTER_APP_INTERFACE_CORRELATION_ID); + + } catch (Exception e) { + notifyProxyClosed("Failed to register application interface with SDL. Check parameter values given to SdlProxy constructor.", e, SdlDisconnectedReason.SDL_REGISTRATION_ERROR); + } + } else { + InternalProxyMessage message = new InternalProxyMessage(InternalProxyMessage.OnProxyOpened); + queueInternalMessage(message); + } + } + + // Queue internal callback message + private void queueInternalMessage(InternalProxyMessage message) { + synchronized(INTERNAL_MESSAGE_QUEUE_THREAD_LOCK) { + if (_internalProxyMessageDispatcher != null) { + _internalProxyMessageDispatcher.queueMessage(message); + } + } + } + + // Queue incoming ProtocolMessage + private void queueIncomingMessage(ProtocolMessage message) { + synchronized(INCOMING_MESSAGE_QUEUE_THREAD_LOCK) { + if (_incomingProxyMessageDispatcher != null) { + _incomingProxyMessageDispatcher.queueMessage(message); + } + } + } + + private FileInputStream getFileInputStream(String sLocalFile) + { + FileInputStream is = null; + try + { + is = new FileInputStream(sLocalFile); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + return is; + } + + private Long getFileInputStreamSize(FileInputStream is) + { + Long lSize = null; + + try + { + lSize = is.getChannel().size(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return lSize; + } + + private void closeFileInputStream(FileInputStream is) + { + try + { + is.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + private RPCStreamController startRPCStream(String sLocalFile, PutFile request, SessionType sType, byte rpcSessionID, Version protocolVersion) + { + if (sdlSession == null) return null; + + FileInputStream is = getFileInputStream(sLocalFile); + if (is == null) return null; + + Long lSize = getFileInputStreamSize(is); + if (lSize == null) + { + closeFileInputStream(is); + return null; + } + + try { + StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, protocolVersion, rpcSpecVersion, lSize, sdlSession); + rpcPacketizer.start(); + return new RPCStreamController(rpcPacketizer, request.getCorrelationID()); + } catch (Exception e) { + Log.e("SyncConnection", "Unable to start streaming:" + e.toString()); + return null; + } + } + + @SuppressWarnings({"unchecked", "UnusedReturnValue"}) + private RPCStreamController startRPCStream(InputStream is, PutFile request, SessionType sType, byte rpcSessionID, Version protocolVersion) + { + if (sdlSession == null) return null; + Long lSize = request.getLength(); + + if (lSize == null) + { + return null; + } + + try { + StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, protocolVersion, rpcSpecVersion, lSize, sdlSession); + rpcPacketizer.start(); + return new RPCStreamController(rpcPacketizer, request.getCorrelationID()); + } catch (Exception e) { + Log.e("SyncConnection", "Unable to start streaming:" + e.toString()); + return null; + } + } + + private RPCStreamController startPutFileStream(String sPath, PutFile msg) { + if (sdlSession == null) return null; + return startRPCStream(sPath, msg, SessionType.RPC, sdlSession.getSessionId(), protocolVersion); + } + + private RPCStreamController startPutFileStream(InputStream is, PutFile msg) { + if (sdlSession == null) return null; + if (is == null) return null; + return startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), protocolVersion); + } + + @SuppressWarnings("UnusedReturnValue") + public boolean startRPCStream(InputStream is, RPCRequest msg) { + if (sdlSession == null) return false; + sdlSession.startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), (byte)getProtocolVersion().getMajor()); + return true; + } + + public OutputStream startRPCStream(RPCRequest msg) { + if (sdlSession == null) return null; + return sdlSession.startRPCStream(msg, SessionType.RPC, sdlSession.getSessionId(), (byte)getProtocolVersion().getMajor()); + } + + public void endRPCStream() { + if (sdlSession == null) return; + sdlSession.stopRPCStream(); + } + + private class CallableMethod implements Callable<Void> { + + private final long waitTime; + + public CallableMethod(int timeInMillis){ + this.waitTime=timeInMillis; + } + @Override + public Void call() { + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + } + + public FutureTask<Void> createFutureTask(CallableMethod callMethod){ + return new FutureTask<Void>(callMethod); + } + + public ScheduledExecutorService createScheduler(){ + return Executors.newSingleThreadScheduledExecutor(); + } + + @SuppressWarnings("unused") + public void startService(SessionType serviceType, boolean isEncrypted){ + sdlSession.startService(serviceType, sdlSession.getSessionId(), isEncrypted); + } + + @SuppressWarnings("unused") + public void endService(SessionType serviceType){ + sdlSession.endService(serviceType, sdlSession.getSessionId()); + } + + + + /** + * @deprecated + *Opens the video service (serviceType 11) and subsequently streams raw H264 video from an InputStream provided by the app + *@return true if service is opened successfully and stream is started, return false otherwise + * @see #startRemoteDisplayStream(Context, Class, VideoStreamingParameters, boolean) startRemoteDisplayStream + * @see #startVideoStream(boolean, VideoStreamingParameters) startVideoStream + * @see #createOpenGLInputSurface(int, int, int, int, int, boolean) createOpenGLInputSurface + */ + @SuppressWarnings("unused") + @Deprecated + public boolean startH264(InputStream is, boolean isEncrypted) { + + if (sdlSession == null) return false; + + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + navServiceStartRejectedParams = null; + + // When startH264() API is used, we will not send video format / width / height information + // with StartService. (Reasons: InputStream does not provide timestamp information so RTP + // cannot be used. startH264() does not provide with/height information.) + VideoStreamingParameters emptyParam = new VideoStreamingParameters(); + emptyParam.setResolution(null); + emptyParam.setFormat(null); + sdlSession.setDesiredVideoParams(emptyParam); + + sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceStartResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + if (navServiceStartResponse) { + try { + sdlSession.startStream(is, SessionType.NAV, sdlSession.getSessionId()); + return true; + } catch (Exception e) { + return false; + } + } else { + return false; + } + } + + /** + * @deprecated + *Opens the video service (serviceType 11) and subsequently provides an OutputStream to the app to use for a raw H264 video stream + *@return OutputStream if service is opened successfully and stream is started, return null otherwise + * @see #startRemoteDisplayStream(Context, Class, VideoStreamingParameters, boolean) startRemoteDisplayStream + * @see #startVideoStream(boolean, VideoStreamingParameters) startVideoStream + * @see #createOpenGLInputSurface(int, int, int, int, int, boolean) createOpenGLInputSurface + */ + @SuppressWarnings("unused") + @Deprecated + public OutputStream startH264(boolean isEncrypted) { + + if (sdlSession == null) return null; + + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + navServiceStartRejectedParams = null; + + // When startH264() API is used, we will not send video format / width / height information + // with StartService. (Reasons: OutputStream does not provide timestamp information so RTP + // cannot be used. startH264() does not provide with/height information.) + VideoStreamingParameters emptyParam = new VideoStreamingParameters(); + emptyParam.setResolution(null); + emptyParam.setFormat(null); + sdlSession.setDesiredVideoParams(emptyParam); + + sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceStartResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + if (navServiceStartResponse) { + try { + return sdlSession.startStream(SessionType.NAV, sdlSession.getSessionId()); + } catch (Exception e) { + return null; + } + } else { + return null; + } + } + + /** + *Closes the opened video service (serviceType 11) + *@return true if the video service is closed successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean endH264() { + return endVideoStream(); + } + /** + *Pauses the stream for the opened audio service (serviceType 10) + *@return true if the audio service stream is paused successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean pausePCM() { + return pauseAudioStream(); + } + + /** + *Pauses the stream for the opened video service (serviceType 11) + *@return true if the video service stream is paused successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean pauseH264() { + return pauseVideoStream(); + } + + /** + *Resumes the stream for the opened audio service (serviceType 10) + *@return true if the audio service stream is resumed successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean resumePCM() { + return resumeAudioStream(); + } + + /** + *Resumes the stream for the opened video service (serviceType 11) + *@return true if the video service is resumed successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean resumeH264() { + return resumeVideoStream(); + } + + + /** + *Opens the audio service (serviceType 10) and subsequently streams raw PCM audio from an InputStream provided by the app + *@return true if service is opened successfully and stream is started, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean startPCM(InputStream is, boolean isEncrypted) { + if (sdlSession == null) return false; + + pcmServiceStartResponseReceived = false; + pcmServiceStartResponse = false; + sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceStartResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + if (pcmServiceStartResponse) { + try { + sdlSession.startStream(is, SessionType.PCM, sdlSession.getSessionId()); + return true; + } catch (Exception e) { + return false; + } + } else { + return false; + } + } + + /** + *Opens the audio service (serviceType 10) and subsequently provides an OutputStream to the app + *@return OutputStream if service is opened successfully and stream is started, return null otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public OutputStream startPCM(boolean isEncrypted) { + if (sdlSession == null) return null; + + pcmServiceStartResponseReceived = false; + pcmServiceStartResponse = false; + sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceStartResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + if (pcmServiceStartResponse) { + try { + return sdlSession.startStream(SessionType.PCM, sdlSession.getSessionId()); + } catch (Exception e) { + return null; + } + } else { + if (pcmServiceStartRejectedParams != null) { + StringBuilder builder = new StringBuilder(); + for (String paramName : pcmServiceStartRejectedParams) { + if (builder.length() > 0) { + builder.append(", "); + } + builder.append(paramName); + } + DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString()); + + } else { + DebugTool.logWarning("StartService for nav failed (rejected params not supplied)"); + } + return null; + } + } + + /** + *Closes the opened audio service (serviceType 10) + *@return true if the audio service is closed successfully, return false otherwise + */ + @SuppressWarnings("unused") + @Deprecated + public boolean endPCM() { + return endAudioStream(); + } + + /** + * Opens a video service (service type 11) and subsequently provides an IVideoStreamListener + * to the app to send video data. The supplied VideoStreamingParameters will be set as desired parameters + * that will be used to negotiate + * + * <br><br><b>NOTE: IF USING SECONDARY TRANSPORTS, THE VIDEO SERVICE MUST BE STARTED BEFORE CALLING THIS + * THIS METHOD. USE A `ISdlServiceListener` TO BE NOTIFIED THAT IT STARTS THEN CALL THIS METHOD TO + * START STREAMING. ADD A LISTENER USE {@link #addServiceListener(SessionType, ISdlServiceListener)}.</b> + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param parameters Video streaming parameters including: codec which will be used for streaming (currently, only + * VideoStreamingCodec.H264 is accepted), height and width of the video in pixels. + * + * @return IVideoStreamListener interface if service is opened successfully and streaming is + * started, null otherwise + * + * @see ISdlServiceListener + */ + @SuppressWarnings("unused") + public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + if (sdlSession == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return null; + } + if (!sdlSession.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return null; + } + + sdlSession.setDesiredVideoParams(parameters); + + VideoStreamingParameters acceptedParams = tryStartVideoStream(isEncrypted, parameters); + if (acceptedParams != null) { + return sdlSession.startVideoStream(); + } else { + return null; + } + } + + /** + *Closes the opened video service (serviceType 11) + *@return true if the video service is closed successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean endVideoStream() { + if (sdlSession == null){ return false; } + + navServiceEndResponseReceived = false; + navServiceEndResponse = false; + sdlSession.stopVideoStream(); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceEndResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + return navServiceEndResponse; + } + + /** + *Pauses the stream for the opened video service (serviceType 11) + *@return true if the video service stream is paused successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean pauseVideoStream() { + return sdlSession != null && sdlSession.pauseVideoStream(); + } + + /** + *Resumes the stream for the opened video service (serviceType 11) + *@return true if the video service is resumed successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean resumeVideoStream() { + return sdlSession != null && sdlSession.resumeVideoStream(); + } + + /** + * Opens the video service (serviceType 11) and creates a Surface (used for streaming video) with input parameters provided by the app + * @param frameRate - specified rate of frames to utilize for creation of Surface + * @param iFrameInterval - specified interval to utilize for creation of Surface + * @param width - specified width to utilize for creation of Surface + * @param height - specified height to utilize for creation of Surface + * @param bitrate - specified bitrate to utilize for creation of Surface + *@return Surface if service is opened successfully and stream is started, return null otherwise + */ + @SuppressWarnings("unused") + public Surface createOpenGLInputSurface(int frameRate, int iFrameInterval, int width, + int height, int bitrate, boolean isEncrypted) { + + if (sdlSession == null || !sdlSession.getIsConnected()){ + return null; + } + + VideoStreamingParameters desired = new VideoStreamingParameters(); + desired.setFrameRate(frameRate); + desired.setInterval(iFrameInterval); + ImageResolution resolution = new ImageResolution(); + resolution.setResolutionWidth(width); + resolution.setResolutionHeight(height); + desired.setResolution(resolution); + desired.setBitrate(bitrate); + + VideoStreamingParameters acceptedParams = tryStartVideoStream(isEncrypted, desired); + if (acceptedParams != null) { + return sdlSession.createOpenGLInputSurface(frameRate, iFrameInterval, width, + height, bitrate, SessionType.NAV, sdlSession.getSessionId()); + } else { + return null; + } + } + + /** + * Starts streaming a remote display to the module if there is a connected session. This method of streaming requires the device to be on API level 19 or higher + * @param context a context that can be used to create the remote display + * @param remoteDisplay class object of the remote display. This class will be used to create an instance of the remote display and will be projected to the module + * @param parameters streaming parameters to be used when streaming. If null is sent in, the default/optimized options will be used. + * If you are unsure about what parameters to be used it is best to just send null and let the system determine what + * works best for the currently connected module. + * + * @param encrypted a flag of if the stream should be encrypted. Only set if you have a supplied encryption library that the module can understand. + */ + @TargetApi(19) + public void startRemoteDisplayStream(Context context, final Class<? extends SdlRemoteDisplay> remoteDisplay, final VideoStreamingParameters parameters, final boolean encrypted){ + if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){ + Log.e(TAG, "Video streaming not supported on this module"); + return; + } + //Create streaming manager + if(manager == null){ + manager = new VideoStreamingManager(context,this._internalInterface); + } + + if(parameters == null){ + if(protocolVersion!= null && protocolVersion.getMajor() >= 5) { + _systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING, new OnSystemCapabilityListener() { + @Override + public void onCapabilityRetrieved(Object capability) { + VideoStreamingParameters params = new VideoStreamingParameters(); + params.update((VideoStreamingCapability)capability); //Streaming parameters are ready time to stream + sdlSession.setDesiredVideoParams(params); + manager.startVideoStreaming(remoteDisplay, params, encrypted); + } + + @Override + public void onError(String info) { + Log.e(TAG, "Error retrieving video streaming capability: " + info); + + } + }); + }else{ + //We just use default video streaming params + VideoStreamingParameters params = new VideoStreamingParameters(); + DisplayCapabilities dispCap = (DisplayCapabilities)_systemCapabilityManager.getCapability(SystemCapabilityType.DISPLAY); + if(dispCap !=null){ + params.setResolution(dispCap.getScreenParams().getImageResolution()); + } + sdlSession.setDesiredVideoParams(params); + manager.startVideoStreaming(remoteDisplay,params, encrypted); + } + }else{ + sdlSession.setDesiredVideoParams(parameters); + manager.startVideoStreaming(remoteDisplay,parameters, encrypted); + } + } + + /** + * Stops the remote display stream if one has been started + */ + public void stopRemoteDisplayStream(){ + if(manager!=null){ + manager.dispose(); + } + manager = null; + } + + /** + * Try to open a video service by using the video streaming parameters supplied. + * + * Only information from codecs, width and height are used during video format negotiation. + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. + * + * @return If the service is opened successfully, an instance of VideoStreamingParams is + * returned which contains accepted video format. If the service is opened with legacy + * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is + * returned. If the service was not opened then null is returned. + */ + @SuppressWarnings("unused") + private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + if (sdlSession == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return null; + } + if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){ + DebugTool.logWarning("Module doesn't support video streaming."); + return null; + } + if (parameters == null) { + DebugTool.logWarning("Video parameters were not supplied."); + return null; + } + + if(!navServiceStartResponseReceived || !navServiceStartResponse //If we haven't started the service before + || (navServiceStartResponse && isEncrypted && !sdlSession.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one + sdlSession.setDesiredVideoParams(parameters); + + navServiceStartResponseReceived = false; + navServiceStartResponse = false; + navServiceStartRejectedParams = null; + + sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!navServiceStartResponseReceived && !fTask.isDone()) ; + scheduler.shutdown(); + } + + if (navServiceStartResponse) { + if(protocolVersion!= null && protocolVersion.getMajor() < 5){ //Versions 1-4 do not support streaming parameter negotiations + sdlSession.setAcceptedVideoParams(parameters); + } + return sdlSession.getAcceptedVideoParams(); + } + + if (navServiceStartRejectedParams != null) { + StringBuilder builder = new StringBuilder(); + for (String paramName : navServiceStartRejectedParams) { + if (builder.length() > 0) { + builder.append(", "); + } + builder.append(paramName); + } + + DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString()); + + } else { + DebugTool.logWarning("StartService for nav failed (rejected params not supplied)"); + } + + return null; + } + + /** + *Starts the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method + */ + @SuppressWarnings("unused") + public void startEncoder () { + if (sdlSession == null || !sdlSession.getIsConnected()) return; + + sdlSession.startEncoder(); + } + + /** + *Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method + */ + @SuppressWarnings("unused") + public void releaseEncoder() { + if (sdlSession == null || !sdlSession.getIsConnected()) return; + + sdlSession.releaseEncoder(); + } + + /** + *Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method + */ + @SuppressWarnings("unused") + public void drainEncoder(boolean endOfStream) { + if (sdlSession == null || !sdlSession.getIsConnected()) return; + + sdlSession.drainEncoder(endOfStream); + } + + /** + * Opens a audio service (service type 10) and subsequently provides an IAudioStreamListener + * to the app to send audio data. + * + * Currently information passed by "params" are ignored, since Audio Streaming feature lacks + * capability negotiation mechanism. App should configure audio stream data to align with + * head unit's capability by checking (upcoming) pcmCapabilities. The default format is in + * 16kHz and 16 bits. + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param codec Audio codec which will be used for streaming. Currently, only + * AudioStreamingCodec.LPCM is accepted. + * @param params (Reserved for future use) Additional configuration information for each + * codec. If "codec" is AudioStreamingCodec.LPCM, "params" must be an + * instance of LPCMParams class. + * + * @return IAudioStreamListener interface if service is opened successfully and streaming is + * started, null otherwise + */ + @SuppressWarnings("unused") + public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, + AudioStreamingParams params) { + if (sdlSession == null) { + DebugTool.logWarning("SdlSession is not created yet."); + return null; + } + if (!sdlSession.getIsConnected()) { + DebugTool.logWarning("Connection is not available."); + return null; + } + if (codec != AudioStreamingCodec.LPCM) { + DebugTool.logWarning("Audio codec " + codec + " is not supported."); + return null; + } + + pcmServiceStartResponseReceived = false; + pcmServiceStartResponse = false; + sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceStartResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + if (pcmServiceStartResponse) { + DebugTool.logInfo("StartService for audio succeeded"); + return sdlSession.startAudioStream(); + } else { + if (pcmServiceStartRejectedParams != null) { + StringBuilder builder = new StringBuilder(); + for (String paramName : pcmServiceStartRejectedParams) { + if (builder.length() > 0) { + builder.append(", "); + } + builder.append(paramName); + } + DebugTool.logWarning("StartService for audio failed. Rejected params: " + builder.toString()); + } else { + DebugTool.logWarning("StartService for audio failed (rejected params not supplied)"); + } + return null; + } + } + + /** + *Closes the opened audio service (serviceType 10) + *@return true if the audio service is closed successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean endAudioStream() { + if (sdlSession == null || !sdlSession.getIsConnected()) return false; + + pcmServiceEndResponseReceived = false; + pcmServiceEndResponse = false; + sdlSession.stopAudioStream(); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!pcmServiceEndResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + return pcmServiceEndResponse; + } + + /** + *Pauses the stream for the opened audio service (serviceType 10) + *@return true if the audio service stream is paused successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean pauseAudioStream() { + return sdlSession != null && sdlSession.pauseAudioStream(); + } + + /** + *Resumes the stream for the opened audio service (serviceType 10) + *@return true if the audio service stream is resumed successfully, return false otherwise + */ + @SuppressWarnings("unused") + public boolean resumeAudioStream() { + return sdlSession != null && sdlSession.resumeAudioStream(); + } + + private void NavServiceStarted() { + navServiceStartResponseReceived = true; + navServiceStartResponse = true; + } + + private void NavServiceStartedNACK(List<String> rejectedParams) { + navServiceStartResponseReceived = true; + navServiceStartResponse = false; + navServiceStartRejectedParams = rejectedParams; + } + + private void AudioServiceStarted() { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = true; + } + + private void RPCProtectedServiceStarted() { + rpcProtectedResponseReceived = true; + rpcProtectedStartResponse = true; + } + private void AudioServiceStartedNACK(List<String> rejectedParams) { + pcmServiceStartResponseReceived = true; + pcmServiceStartResponse = false; + pcmServiceStartRejectedParams = rejectedParams; + } + + private void NavServiceEnded() { + navServiceEndResponseReceived = true; + navServiceEndResponse = true; + } + + private void NavServiceEndedNACK() { + navServiceEndResponseReceived = true; + navServiceEndResponse = false; + } + + private void AudioServiceEnded() { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = true; + } + + private void AudioServiceEndedNACK() { + pcmServiceEndResponseReceived = true; + pcmServiceEndResponse = false; + } + + public void setAppService(Service mService) + { + _appService = mService; + } + + @SuppressWarnings("unused") + public boolean startProtectedRPCService() { + rpcProtectedResponseReceived = false; + rpcProtectedStartResponse = false; + sdlSession.startService(SessionType.RPC, sdlSession.getSessionId(), true); + + FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME)); + ScheduledExecutorService scheduler = createScheduler(); + scheduler.execute(fTask); + + //noinspection StatementWithEmptyBody + while (!rpcProtectedResponseReceived && !fTask.isDone()); + scheduler.shutdown(); + + return rpcProtectedStartResponse; + } + + @SuppressWarnings("unused") + public void getLockScreenIcon(final OnLockScreenIconDownloadedListener l){ + if(lockScreenIconRequest == null){ + l.onLockScreenIconDownloadError(new SdlException("This version of SDL core may not support lock screen icons.", + SdlExceptionCause.LOCK_SCREEN_ICON_NOT_SUPPORTED)); + return; + } + + LockScreenManager lockMan = sdlSession.getLockScreenMan(); + Bitmap bitmap = lockMan.getLockScreenIcon(); + + // read bitmap if it was already downloaded so we don't have to download it every time + if(bitmap != null){ + l.onLockScreenIconDownloaded(bitmap); + } + else{ + String url = lockScreenIconRequest.getUrl(); + sdlSession.getLockScreenMan().downloadLockScreenIcon(url, l); + } + } + + /* ******************* Public Helper Methods *************************/ + + /*Begin V1 Enhanced helper*/ + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param parentID -Menu parent ID for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param vrCommands -VR synonyms for this AddCommand. + *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + *@param IconType -Describes whether the image is static or dynamic + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void addCommand(@NonNull Integer commandID, + String menuText, Integer parentID, Integer position, + Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID) + throws SdlException { + + + AddCommand msg = new AddCommand(commandID); + msg.setCorrelationID(correlationID); + + if (vrCommands != null) msg.setVrCommands(vrCommands); + + Image cmdIcon = null; + + if (IconValue != null && IconType != null) + { + cmdIcon = new Image(); + cmdIcon.setValue(IconValue); + cmdIcon.setImageType(IconType); + } + + if (cmdIcon != null) msg.setCmdIcon(cmdIcon); + + if(menuText != null || parentID != null || position != null) { + MenuParams menuParams = new MenuParams(); + menuParams.setMenuName(menuText); + menuParams.setPosition(position); + menuParams.setParentID(parentID); + msg.setMenuParams(menuParams); + } + + sendRPCRequest(msg); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param vrCommands -VR synonyms for this AddCommand. + *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + *@param IconType -Describes whether the image is static or dynamic + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Integer position, + Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, position, vrCommands, IconValue, IconType, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + *@param IconType -Describes whether the image is static or dynamic + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Integer position, String IconValue, ImageType IconType, + Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, position, null, IconValue, IconType, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + *@param IconType -Describes whether the image is static or dynamic + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, String IconValue, ImageType IconType, Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, null, null, IconValue, IconType, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param commandID -Unique command ID of the command to add. + * @param menuText -Menu text for optional sub value containing menu parameters. + * @param vrCommands -VR synonyms for this AddCommand. + * @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + * @param IconType -Describes whether the image is static or dynamic + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, null, vrCommands, IconValue, IconType, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param commandID -Unique command ID of the command to add. + * @param vrCommands -VR synonyms for this AddCommand. + * @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC). + * @param IconType -Describes whether the image is static or dynamic + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID) + throws SdlException { + + addCommand(commandID, null, null, null, vrCommands, IconValue, IconType, correlationID); + } + + /*End V1 Enhanced helper*/ + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param parentID -Menu parent ID for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param vrCommands -VR synonyms for this AddCommand. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void addCommand(@NonNull Integer commandID, + String menuText, Integer parentID, Integer position, + Vector<String> vrCommands, Integer correlationID) + throws SdlException { + + AddCommand msg = new AddCommand(commandID); + msg.setCorrelationID(correlationID); + msg.setVrCommands(vrCommands); + if(menuText != null || parentID != null || position != null) { + MenuParams menuParams = new MenuParams(); + menuParams.setMenuName(menuText); + menuParams.setPosition(position); + menuParams.setParentID(parentID); + msg.setMenuParams(menuParams); + } + + sendRPCRequest(msg); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param vrCommands -VR synonyms for this AddCommand. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Integer position, + Vector<String> vrCommands, Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, position, vrCommands, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param position -Menu position for optional sub value containing menu parameters. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Integer position, + Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, position, null, correlationID); + } + + /** + *Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Integer correlationID) + throws SdlException { + addCommand(commandID, menuText, null, null, (Vector<String>)null, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param menuText -Menu text for optional sub value containing menu parameters. + *@param vrCommands -VR synonyms for this AddCommand. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + String menuText, Vector<String> vrCommands, Integer correlationID) + throws SdlException { + + addCommand(commandID, menuText, null, null, vrCommands, correlationID); + } + + /** + * Sends an AddCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + *@param commandID -Unique command ID of the command to add. + *@param vrCommands -VR synonyms for this AddCommand. + *@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void addCommand(Integer commandID, + Vector<String> vrCommands, Integer correlationID) + throws SdlException { + + addCommand(commandID, null, null, null, vrCommands, correlationID); + } + + /** + * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param menuID -Unique ID of the sub menu to add. + * @param menuName -Text to show in the menu for this sub menu. + * @param position -Position within the items that are are at top level of the in application menu. + * @param menuIcon -Image to be be shown along with the submenu item + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void addSubMenu(@NonNull Integer menuID, @NonNull String menuName, + Integer position, Image menuIcon, Integer correlationID) + throws SdlException { + + AddSubMenu msg = new AddSubMenu(menuID, menuName); + msg.setCorrelationID(correlationID); + msg.setPosition(position); + msg.setMenuIcon(menuIcon); + + sendRPCRequest(msg); + } + + /** + * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param menuID -Unique ID of the sub menu to add. + * @param menuName -Text to show in the menu for this sub menu. + * @param position -Position within the items that are are at top level of the in application menu. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @Deprecated + @SuppressWarnings("SameParameterValue") + public void addSubMenu(@NonNull Integer menuID, @NonNull String menuName, + Integer position, Integer correlationID) + throws SdlException { + + addSubMenu(menuID, menuName, position, null, correlationID); + } + + /** + * Sends an AddSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param menuID -Unique ID of the sub menu to add. + * @param menuName -Text to show in the menu for this sub menu. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @Deprecated + @SuppressWarnings("unused") + public void addSubMenu(Integer menuID, String menuName, + Integer correlationID) throws SdlException { + + addSubMenu(menuID, menuName, null, null, correlationID); + } + + /*Begin V1 Enhanced helper*/ + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsText -The text to speech message in the form of a string. + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param alertText3 -The optional third line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param softButtons -A list of App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void alert(String ttsText, String alertText1, + String alertText2, String alertText3, Boolean playTone, Integer duration, Vector<SoftButton> softButtons, + Integer correlationID) throws SdlException { + + Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(ttsText); + Alert msg = new Alert(); + msg.setCorrelationID(correlationID); + msg.setAlertText1(alertText1); + msg.setAlertText2(alertText2); + msg.setAlertText3(alertText3); + msg.setDuration(duration); + msg.setPlayTone(playTone); + msg.setTtsChunks(chunks); + msg.setSoftButtons(softButtons); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsChunks -Text/phonemes to speak in the form of ttsChunks. + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param alertText3 -The optional third line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param softButtons -A list of App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + public void alert(Vector<TTSChunk> ttsChunks, + String alertText1, String alertText2, String alertText3, Boolean playTone, + Integer duration, Vector<SoftButton> softButtons, Integer correlationID) throws SdlException { + + Alert msg = new Alert(); + msg.setCorrelationID(correlationID); + msg.setAlertText1(alertText1); + msg.setAlertText2(alertText2); + msg.setAlertText3(alertText3); + msg.setDuration(duration); + msg.setPlayTone(playTone); + msg.setTtsChunks(ttsChunks); + msg.setSoftButtons(softButtons); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsText -The text to speech message in the form of a string. + * @param playTone -Defines if tone should be played. + * @param softButtons -A list of App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(String ttsText, Boolean playTone, Vector<SoftButton> softButtons, + Integer correlationID) throws SdlException { + + alert(ttsText, null, null, null, playTone, null, softButtons, correlationID); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param chunks -A list of text/phonemes to speak in the form of ttsChunks. + * @param playTone -Defines if tone should be played. + * @param softButtons -A list of App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(Vector<TTSChunk> chunks, Boolean playTone, Vector<SoftButton> softButtons, + Integer correlationID) throws SdlException { + + alert(chunks, null, null, null, playTone, null, softButtons, correlationID); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param alertText3 -The optional third line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param softButtons -A list of App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(String alertText1, String alertText2, String alertText3, + Boolean playTone, Integer duration, Vector<SoftButton> softButtons, Integer correlationID) + throws SdlException { + + alert((Vector<TTSChunk>)null, alertText1, alertText2, alertText3, playTone, duration, softButtons, correlationID); + } + + /*End V1 Enhanced helper*/ + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsText -The text to speech message in the form of a string. + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void alert(String ttsText, String alertText1, + String alertText2, Boolean playTone, Integer duration, + Integer correlationID) throws SdlException { + + Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(ttsText); + Alert msg = new Alert(); + msg.setCorrelationID(correlationID); + msg.setAlertText1(alertText1); + msg.setAlertText2(alertText2); + msg.setDuration(duration); + msg.setPlayTone(playTone); + msg.setTtsChunks(chunks); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsChunks -A list of text/phonemes to speak in the form of ttsChunks. + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + public void alert(Vector<TTSChunk> ttsChunks, + String alertText1, String alertText2, Boolean playTone, + Integer duration, Integer correlationID) throws SdlException { + + Alert msg = new Alert(); + msg.setCorrelationID(correlationID); + msg.setAlertText1(alertText1); + msg.setAlertText2(alertText2); + msg.setDuration(duration); + msg.setPlayTone(playTone); + msg.setTtsChunks(ttsChunks); + + sendRPCRequest(msg); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsText -The text to speech message in the form of a string. + * @param playTone -Defines if tone should be played. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(String ttsText, Boolean playTone, + Integer correlationID) throws SdlException { + + alert(ttsText, null, null, playTone, null, correlationID); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param chunks -A list of text/phonemes to speak in the form of ttsChunks. + * @param playTone -Defines if tone should be played. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(Vector<TTSChunk> chunks, Boolean playTone, + Integer correlationID) throws SdlException { + + alert(chunks, null, null, playTone, null, correlationID); + } + + /** + * Sends an Alert RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param alertText1 -The first line of the alert text field. + * @param alertText2 -The second line of the alert text field. + * @param playTone -Defines if tone should be played. + * @param duration -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void alert(String alertText1, String alertText2, + Boolean playTone, Integer duration, Integer correlationID) + throws SdlException { + + alert((Vector<TTSChunk>)null, alertText1, alertText2, playTone, duration, correlationID); + } + + /** + * Sends a CreateInteractionChoiceSet RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param choiceSet to be sent to the module + * @param interactionChoiceSetID to be used in reference to the supplied choiceSet + * @param correlationID to be set to the RPCRequest + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void createInteractionChoiceSet( + @NonNull Vector<Choice> choiceSet, @NonNull Integer interactionChoiceSetID, + Integer correlationID) throws SdlException { + + CreateInteractionChoiceSet msg = new CreateInteractionChoiceSet(interactionChoiceSetID, choiceSet); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteCommand RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param commandID -ID of the command(s) to delete. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void deleteCommand(@NonNull Integer commandID, + Integer correlationID) throws SdlException { + + DeleteCommand msg = new DeleteCommand(commandID); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteInteractionChoiceSet RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param interactionChoiceSetID -ID of the interaction choice set to delete. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void deleteInteractionChoiceSet( + @NonNull Integer interactionChoiceSetID, Integer correlationID) + throws SdlException { + + DeleteInteractionChoiceSet msg = new DeleteInteractionChoiceSet(interactionChoiceSetID); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a DeleteSubMenu RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param menuID -The menuID of the submenu to delete. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void deleteSubMenu(Integer menuID, + Integer correlationID) throws SdlException { + + DeleteSubMenu msg = new DeleteSubMenu(menuID); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + + /*Begin V1 Enhanced helper*/ + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction. + * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Integer interactionChoiceSetID, Vector<VrHelpItem> vrHelp, + Integer correlationID) throws SdlException { + + Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>(); + interactionChoiceSetIDs.add(interactionChoiceSetID); + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + PerformInteraction msg = new PerformInteraction(displayText, InteractionMode.BOTH, interactionChoiceSetIDs); + msg.setInitialPrompt(initChunks); + msg.setVrHelp(vrHelp); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction. + * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Integer interactionChoiceSetID, + String helpPrompt, String timeoutPrompt, + @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp, + Integer correlationID) throws SdlException { + + Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>(); + interactionChoiceSetIDs.add(interactionChoiceSetID); + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt); + Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt); + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDs); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setVrHelp(vrHelp); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction. + * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Vector<Integer> interactionChoiceSetIDList, + String helpPrompt, String timeoutPrompt, + @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp, + Integer correlationID) throws SdlException { + + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt); + Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt); + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setVrHelp(vrHelp); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initChunks -A list of text/phonemes to speak for the initial prompt in the form of ttsChunks. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction. + * @param helpChunks -A list of text/phonemes to speak for the help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutChunks A list of text/phonems to speak for the timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction( + Vector<TTSChunk> initChunks, @NonNull String displayText, + @NonNull Vector<Integer> interactionChoiceSetIDList, + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + @NonNull InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp, + Integer correlationID) throws SdlException { + + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setVrHelp(vrHelp); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /*End V1 Enhanced*/ + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Integer interactionChoiceSetID, + Integer correlationID) throws SdlException { + + Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>(); + interactionChoiceSetIDs.add(interactionChoiceSetID); + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + PerformInteraction msg = new PerformInteraction(displayText, InteractionMode.BOTH, interactionChoiceSetIDs); + msg.setInitialPrompt(initChunks); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction. + * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Integer interactionChoiceSetID, + String helpPrompt, String timeoutPrompt, + @NonNull InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SdlException { + + Vector<Integer> interactionChoiceSetIDs = new Vector<Integer>(); + interactionChoiceSetIDs.add(interactionChoiceSetID); + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt); + Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt); + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDs); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initPrompt -Intial prompt spoken to the user at the start of an interaction. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction. + * @param helpPrompt -Help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutPrompt -Timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction(String initPrompt, + @NonNull String displayText, @NonNull Vector<Integer> interactionChoiceSetIDList, + String helpPrompt, String timeoutPrompt, + @NonNull InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SdlException { + + Vector<TTSChunk> initChunks = TTSChunkFactory.createSimpleTTSChunks(initPrompt); + Vector<TTSChunk> helpChunks = TTSChunkFactory.createSimpleTTSChunks(helpPrompt); + Vector<TTSChunk> timeoutChunks = TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt); + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a PerformInteraction RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param initChunks -A list of text/phonemes to speak for the initial prompt in the form of ttsChunks. + * @param displayText -Text to be displayed first. + * @param interactionChoiceSetIDList -A list of interaction choice set IDs to use with an interaction. + * @param helpChunks -A list of text/phonemes to speak for the help text that is spoken when a user speaks "help" during the interaction. + * @param timeoutChunks A list of text/phonems to speak for the timeout text that is spoken when a VR interaction times out. + * @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both). + * @param timeout -Timeout in milliseconds. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performInteraction( + Vector<TTSChunk> initChunks, @NonNull String displayText, + @NonNull Vector<Integer> interactionChoiceSetIDList, + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + @NonNull InteractionMode interactionMode, Integer timeout, + Integer correlationID) throws SdlException { + + PerformInteraction msg = new PerformInteraction(displayText, interactionMode, interactionChoiceSetIDList); + msg.setInitialPrompt(initChunks); + msg.setTimeout(timeout); + msg.setHelpPrompt(helpChunks); + msg.setTimeoutPrompt(timeoutChunks); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + // Protected registerAppInterface used to ensure only non-ALM applications call + // reqisterAppInterface + protected void registerAppInterfacePrivate( + @NonNull SdlMsgVersion sdlMsgVersion, @NonNull String appName, Vector<TTSChunk> ttsName, + String ngnMediaScreenAppName, Vector<String> vrSynonyms, @NonNull Boolean isMediaApp, + @NonNull Language languageDesired, @NonNull Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, + @NonNull String appID, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, Integer correlationID) + throws SdlException { + String carrierName = null; + if(telephonyManager != null){ + carrierName = telephonyManager.getNetworkOperatorName(); + } + + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setHardware(android.os.Build.MODEL); + deviceInfo.setOs(DeviceInfo.DEVICE_OS); + deviceInfo.setOsVersion(Build.VERSION.RELEASE); + deviceInfo.setCarrier(carrierName); + + if (sdlMsgVersion == null) { + sdlMsgVersion = new SdlMsgVersion(); + if(protocolVersion.getMajor() == 1) { + DebugTool.logInfo("Connected to an older module, must send 1.0.0 as RPC spec"); + sdlMsgVersion.setMajorVersion(1); + sdlMsgVersion.setMinorVersion(0); + }else { + sdlMsgVersion.setMajorVersion(MAX_SUPPORTED_RPC_VERSION.getMajor()); + sdlMsgVersion.setMinorVersion(MAX_SUPPORTED_RPC_VERSION.getMinor()); + } + } + if (languageDesired == null) { + languageDesired = Language.EN_US; + } + if (hmiDisplayLanguageDesired == null) { + hmiDisplayLanguageDesired = Language.EN_US; + } + + RegisterAppInterface msg = new RegisterAppInterface(sdlMsgVersion, appName, isMediaApp, languageDesired, hmiDisplayLanguageDesired, appID); + + if (correlationID != null) { + msg.setCorrelationID(correlationID); + } + + msg.setDeviceInfo(deviceInfo); + + msg.setTtsName(ttsName); + + if (ngnMediaScreenAppName == null) { + ngnMediaScreenAppName = appName; + } + + msg.setNgnMediaScreenAppName(ngnMediaScreenAppName); + + if (vrSynonyms == null) { + vrSynonyms = new Vector<String>(); + vrSynonyms.add(appName); + } + msg.setVrSynonyms(vrSynonyms); + + msg.setAppHMIType(appType); + + msg.setDayColorScheme(dayColorScheme); + msg.setNightColorScheme(nightColorScheme); + + if (_bAppResumeEnabled) + { + if (_lastHashID != null) + msg.setHashID(_lastHashID); + } + + Intent sendIntent = createBroadcastIntent(); + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.REGISTER_APP_INTERFACE.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_REQUEST); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + sendBroadcastIntent(sendIntent); + + sendRPCMessagePrivate(msg); + } + + /*Begin V1 Enhanced helper function*/ + + /** + * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param helpPrompt that will be used for the VR screen + * @param timeoutPrompt string to be displayed after timeout + * @param vrHelpTitle string that may be displayed on VR prompt dialog + * @param vrHelp a list of VR synonyms that may be displayed to user + * @param correlationID to be attached to the request + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setGlobalProperties( + String helpPrompt, String timeoutPrompt, String vrHelpTitle, Vector<VrHelpItem> vrHelp, Integer correlationID) + throws SdlException { + + SetGlobalProperties req = new SetGlobalProperties(); + req.setCorrelationID(correlationID); + req.setHelpPrompt(TTSChunkFactory.createSimpleTTSChunks(helpPrompt)); + req.setTimeoutPrompt(TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt)); + req.setVrHelpTitle(vrHelpTitle); + req.setVrHelp(vrHelp); + + sendRPCRequest(req); + } + + /** + * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param helpChunks tts chunks that should be used when prompting the user + * @param timeoutChunks tts chunks that will be used when a timeout occurs + * @param vrHelpTitle string that may be displayed on VR prompt dialog + * @param vrHelp a list of VR synonyms that may be displayed to user + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setGlobalProperties( + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, String vrHelpTitle, Vector<VrHelpItem> vrHelp, + Integer correlationID) throws SdlException { + + SetGlobalProperties req = new SetGlobalProperties(); + req.setCorrelationID(correlationID); + req.setHelpPrompt(helpChunks); + req.setTimeoutPrompt(timeoutChunks); + req.setVrHelpTitle(vrHelpTitle); + req.setVrHelp(vrHelp); + + sendRPCRequest(req); + } + + /*End V1 Enhanced helper function*/ + + /** + * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param helpPrompt that will be used for the VR screen + * @param timeoutPrompt string to be displayed after timeout + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setGlobalProperties( + String helpPrompt, String timeoutPrompt, Integer correlationID) + throws SdlException { + + SetGlobalProperties req = new SetGlobalProperties(); + req.setCorrelationID(correlationID); + req.setHelpPrompt(TTSChunkFactory.createSimpleTTSChunks(helpPrompt)); + req.setTimeoutPrompt(TTSChunkFactory.createSimpleTTSChunks(timeoutPrompt)); + + sendRPCRequest(req); + } + + /** + * Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param helpChunks tts chunks that should be used when prompting the user + * @param timeoutChunks tts chunks that will be used when a timeout occurs + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setGlobalProperties( + Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, + Integer correlationID) throws SdlException { + + SetGlobalProperties req = new SetGlobalProperties(); + req.setCorrelationID(correlationID); + req.setHelpPrompt(helpChunks); + req.setTimeoutPrompt(timeoutChunks); + + sendRPCRequest(req); + } + + @SuppressWarnings("unused") + public void resetGlobalProperties(Vector<GlobalProperty> properties, + Integer correlationID) throws SdlException { + + ResetGlobalProperties req = new ResetGlobalProperties(); + + req.setCorrelationID(correlationID); + req.setProperties(properties); + + sendRPCRequest(req); + } + + + /** + * Sends a SetMediaClockTimer RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param hours integer for hours + * @param minutes integer for minutes + * @param seconds integer for seconds + * @param updateMode mode in which the media clock timer should be updated + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setMediaClockTimer(Integer hours, + Integer minutes, Integer seconds, @NonNull UpdateMode updateMode, + Integer correlationID) throws SdlException { + + SetMediaClockTimer msg = new SetMediaClockTimer(updateMode); + if (hours != null || minutes != null || seconds != null) { + StartTime startTime = new StartTime(hours, minutes, seconds); + msg.setStartTime(startTime); + } + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Pauses the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void pauseMediaClockTimer(Integer correlationID) + throws SdlException { + + SetMediaClockTimer msg = new SetMediaClockTimer(UpdateMode.PAUSE); + StartTime startTime = new StartTime(0, 0, 0); + msg.setStartTime(startTime); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Resumes the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void resumeMediaClockTimer(Integer correlationID) + throws SdlException { + + SetMediaClockTimer msg = new SetMediaClockTimer(UpdateMode.RESUME); + StartTime startTime = new StartTime(0, 0, 0); + msg.setStartTime(startTime); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Clears the media clock. Responses are captured through callback on IProxyListener. + * + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void clearMediaClockTimer(Integer correlationID) + throws SdlException { + + Show msg = new Show(); + msg.setCorrelationID(correlationID); + msg.setMediaClock(" "); + + sendRPCRequest(msg); + } + + /*Begin V1 Enhanced helper*/ + /** + * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param mainText1 text displayed in a single or upper display line. + * @param mainText2 text displayed on the second display line. + * @param mainText3 text displayed on the second "page" first display line. + * @param mainText4 text displayed on the second "page" second display line. + * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps) + * @param mediaClock text value for MediaClock field. + * @param mediaTrack text displayed in the track field. + * @param graphic image struct determining whether static or dynamic image to display in app. + * @param softButtons app defined SoftButtons. + * @param customPresets app labeled on-screen presets. + * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display. + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void show(String mainText1, String mainText2, String mainText3, String mainText4, + String statusBar, String mediaClock, String mediaTrack, + Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets, + TextAlignment alignment, Integer correlationID) + throws SdlException { + + Show msg = new Show(); + msg.setCorrelationID(correlationID); + msg.setMainField1(mainText1); + msg.setMainField2(mainText2); + msg.setStatusBar(statusBar); + msg.setMediaClock(mediaClock); + msg.setMediaTrack(mediaTrack); + msg.setAlignment(alignment); + msg.setMainField3(mainText3); + msg.setMainField4(mainText4); + msg.setGraphic(graphic); + msg.setSoftButtons(softButtons); + msg.setCustomPresets(customPresets); + + sendRPCRequest(msg); + } + + /** + * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param mainText1 -Text displayed in a single or upper display line. + * @param mainText2 -Text displayed on the second display line. + * @param mainText3 -Text displayed on the second "page" first display line. + * @param mainText4 -Text displayed on the second "page" second display line. + * @param graphic -Image struct determining whether static or dynamic image to display in app. + * @param softButtons -App defined SoftButtons. + * @param customPresets -App labeled on-screen presets. + * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void show(String mainText1, String mainText2, String mainText3, String mainText4, + Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets, + TextAlignment alignment, Integer correlationID) + throws SdlException { + + show(mainText1, mainText2, mainText3, mainText4, null, null, null, graphic, softButtons, customPresets, alignment, correlationID); + } + /*End V1 Enhanced helper*/ + + /** + * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param mainText1 text displayed in a single or upper display line. + * @param mainText2 text displayed on the second display line. + * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps) + * @param mediaClock text value for MediaClock field. + * @param mediaTrack text displayed in the track field. + * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display. + * @param correlationID unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("SameParameterValue") + public void show(String mainText1, String mainText2, + String statusBar, String mediaClock, String mediaTrack, + TextAlignment alignment, Integer correlationID) + throws SdlException { + + Show msg = new Show(); + msg.setCorrelationID(correlationID); + msg.setMainField1(mainText1); + msg.setMainField2(mainText2); + msg.setStatusBar(statusBar); + msg.setMediaClock(mediaClock); + msg.setMediaTrack(mediaTrack); + msg.setAlignment(alignment); + + sendRPCRequest(msg); + } + + /** + * Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param mainText1 -Text displayed in a single or upper display line. + * @param mainText2 -Text displayed on the second display line. + * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void show(String mainText1, String mainText2, + TextAlignment alignment, Integer correlationID) + throws SdlException { + + show(mainText1, mainText2, null, null, null, alignment, correlationID); + } + + /** + * Sends a Speak RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsText -The text to speech message in the form of a string. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void speak(@NonNull String ttsText, Integer correlationID) + throws SdlException { + + Speak msg = new Speak(TTSChunkFactory.createSimpleTTSChunks(ttsText)); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a Speak RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param ttsChunks -Text/phonemes to speak in the form of ttsChunks. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void speak(@NonNull Vector<TTSChunk> ttsChunks, + Integer correlationID) throws SdlException { + + Speak msg = new Speak(ttsChunks); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Sends a SubscribeButton RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param buttonName -Name of the button to subscribe. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void subscribeButton(@NonNull ButtonName buttonName, + Integer correlationID) throws SdlException { + + SubscribeButton msg = new SubscribeButton(buttonName); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + // Protected unregisterAppInterface used to ensure no non-ALM app calls + // unregisterAppInterface. + protected void unregisterAppInterfacePrivate(Integer correlationID) + throws SdlException { + + UnregisterAppInterface msg = new UnregisterAppInterface(); + msg.setCorrelationID(correlationID); + + Intent sendIntent = createBroadcastIntent(); + + updateBroadcastIntent(sendIntent, "RPC_NAME", FunctionID.UNREGISTER_APP_INTERFACE.toString()); + updateBroadcastIntent(sendIntent, "TYPE", RPCMessage.KEY_REQUEST); + updateBroadcastIntent(sendIntent, "CORRID", msg.getCorrelationID()); + updateBroadcastIntent(sendIntent, "DATA",serializeJSON(msg)); + sendBroadcastIntent(sendIntent); + + sendRPCMessagePrivate(msg); + } + + /** + * Sends an UnsubscribeButton RPCRequest to SDL. Responses are captured through callback on IProxyListener. + * + * @param buttonName -Name of the button to unsubscribe. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void unsubscribeButton(@NonNull ButtonName buttonName, + Integer correlationID) throws SdlException { + + UnsubscribeButton msg = new UnsubscribeButton(buttonName); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Creates a choice to be added to a choiceset. Choice has both a voice and a visual menu component. + * + * @param choiceID -Unique ID used to identify this choice (returned in callback). + * @param choiceMenuName -Text name displayed for this choice. + * @param choiceVrCommands -Vector of vrCommands used to select this choice by voice. Must contain + * at least one non-empty element. + * @return Choice created. + */ + @SuppressWarnings("unused") + public Choice createChoiceSetChoice(Integer choiceID, String choiceMenuName, + Vector<String> choiceVrCommands) { + Choice returnChoice = new Choice(); + + returnChoice.setChoiceID(choiceID); + returnChoice.setMenuName(choiceMenuName); + returnChoice.setVrCommands(choiceVrCommands); + + return returnChoice; + } + + /** + * Starts audio pass thru session. Responses are captured through callback on IProxyListener. + * + * @param initialPrompt -SDL will speak this prompt before opening the audio pass thru session. + * @param audioPassThruDisplayText1 -First line of text displayed during audio capture. + * @param audioPassThruDisplayText2 -Second line of text displayed during audio capture. + * @param samplingRate -Allowable values of 8 khz or 16 or 22 or 44 khz. + * @param maxDuration -The maximum duration of audio recording in milliseconds. + * @param bitsPerSample -Specifies the quality the audio is recorded. Currently 8 bit or 16 bit. + * @param audioType -Specifies the type of audio data being requested. + * @param muteAudio -Defines if the current audio source should be muted during the APT session. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void performaudiopassthru(String initialPrompt, String audioPassThruDisplayText1, String audioPassThruDisplayText2, + @NonNull SamplingRate samplingRate, @NonNull Integer maxDuration, @NonNull BitsPerSample bitsPerSample, + @NonNull AudioType audioType, Boolean muteAudio, Integer correlationID) throws SdlException { + Vector<TTSChunk> chunks = TTSChunkFactory.createSimpleTTSChunks(initialPrompt); + PerformAudioPassThru msg = new PerformAudioPassThru(samplingRate, maxDuration, bitsPerSample, audioType); + msg.setCorrelationID(correlationID); + msg.setInitialPrompt(chunks); + msg.setAudioPassThruDisplayText1(audioPassThruDisplayText1); + msg.setAudioPassThruDisplayText2(audioPassThruDisplayText2); + msg.setMuteAudio(muteAudio); + + sendRPCRequest(msg); + } + + /** + * Ends audio pass thru session. Responses are captured through callback on IProxyListener. + * + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void endaudiopassthru(Integer correlationID) throws SdlException + { + EndAudioPassThru msg = new EndAudioPassThru(); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Subscribes for specific published data items. The data will be only sent if it has changed. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Subscribes to GPS data. + * @param speed -Subscribes to vehicle speed data in kilometers per hour. + * @param rpm -Subscribes to number of revolutions per minute of the engine. + * @param fuelLevel -Subscribes to fuel level in the tank (percentage). + * @param fuelLevel_State -Subscribes to fuel level state. + * @param instantFuelConsumption -Subscribes to instantaneous fuel consumption in microlitres. + * @param externalTemperature -Subscribes to the external temperature in degrees celsius. + * @param prndl -Subscribes to PRNDL data that houses the selected gear. + * @param tirePressure -Subscribes to the TireStatus data containing status and pressure of tires. + * @param odometer -Subscribes to Odometer data in km. + * @param beltStatus -Subscribes to status of the seat belts. + * @param bodyInformation -Subscribes to body information including power modes. + * @param deviceStatus -Subscribes to device status including signal and battery strength. + * @param driverBraking -Subscribes to the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + @Deprecated + public void subscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure, + boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + SubscribeVehicleData msg = new SubscribeVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Subscribes for specific published data items. The data will be only sent if it has changed. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Subscribes to GPS data. + * @param speed -Subscribes to vehicle speed data in kilometers per hour. + * @param rpm -Subscribes to number of revolutions per minute of the engine. + * @param fuelLevel -Subscribes to fuel level in the tank (percentage). + * @param fuelLevel_State -Subscribes to fuel level state. + * @param instantFuelConsumption -Subscribes to instantaneous fuel consumption in microlitres. + * @param externalTemperature -Subscribes to the external temperature in degrees celsius. + * @param prndl -Subscribes to PRNDL data that houses the selected gear. + * @param tirePressure -Subscribes to the TireStatus data containing status and pressure of tires. + * @param engineOilLife -Subscribes to Engine Oil Life data. + * @param odometer -Subscribes to Odometer data in km. + * @param beltStatus -Subscribes to status of the seat belts. + * @param bodyInformation -Subscribes to body information including power modes. + * @param deviceStatus -Subscribes to device status including signal and battery strength. + * @param driverBraking -Subscribes to the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void subscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure, + boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + SubscribeVehicleData msg = new SubscribeVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setEngineOilLife(engineOilLife); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Unsubscribes for specific published data items. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Unsubscribes to GPS data. + * @param speed -Unsubscribes to vehicle speed data in kilometers per hour. + * @param rpm -Unsubscribes to number of revolutions per minute of the engine. + * @param fuelLevel -Unsubscribes to fuel level in the tank (percentage). + * @param fuelLevel_State -Unsubscribes to fuel level state. + * @param instantFuelConsumption -Unsubscribes to instantaneous fuel consumption in microlitres. + * @param externalTemperature -Unsubscribes to the external temperature in degrees celsius. + * @param prndl -Unsubscribes to PRNDL data that houses the selected gear. + * @param tirePressure -Unsubscribes to the TireStatus data containing status and pressure of tires. + * @param odometer -Unsubscribes to Odometer data in km. + * @param beltStatus -Unsubscribes to status of the seat belts. + * @param bodyInformation -Unsubscribes to body information including power modes. + * @param deviceStatus -Unsubscribes to device status including signal and battery strength. + * @param driverBraking -Unsubscribes to the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + + @SuppressWarnings("unused") + @Deprecated + public void unsubscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure, + boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + UnsubscribeVehicleData msg = new UnsubscribeVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Unsubscribes for specific published data items. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Unsubscribes to GPS data. + * @param speed -Unsubscribes to vehicle speed data in kilometers per hour. + * @param rpm -Unsubscribes to number of revolutions per minute of the engine. + * @param fuelLevel -Unsubscribes to fuel level in the tank (percentage). + * @param fuelLevel_State -Unsubscribes to fuel level state. + * @param instantFuelConsumption -Unsubscribes to instantaneous fuel consumption in microlitres. + * @param externalTemperature -Unsubscribes to the external temperature in degrees celsius. + * @param prndl -Unsubscribes to PRNDL data that houses the selected gear. + * @param tirePressure -Unsubscribes to the TireStatus data containing status and pressure of tires. + * @param engineOilLife -Unsubscribes to Engine Oil Life data. + * @param odometer -Unsubscribes to Odometer data in km. + * @param beltStatus -Unsubscribes to status of the seat belts. + * @param bodyInformation -Unsubscribes to body information including power modes. + * @param deviceStatus -Unsubscribes to device status including signal and battery strength. + * @param driverBraking -Unsubscribes to the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + + @SuppressWarnings("unused") + public void unsubscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure, + boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + UnsubscribeVehicleData msg = new UnsubscribeVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setEngineOilLife(engineOilLife); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Performs a Non periodic vehicle data read request. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Performs an ad-hoc request for GPS data. + * @param speed -Performs an ad-hoc request for vehicle speed data in kilometers per hour. + * @param rpm -Performs an ad-hoc request for number of revolutions per minute of the engine. + * @param fuelLevel -Performs an ad-hoc request for fuel level in the tank (percentage). + * @param fuelLevel_State -Performs an ad-hoc request for fuel level state. + * @param instantFuelConsumption -Performs an ad-hoc request for instantaneous fuel consumption in microlitres. + * @param externalTemperature -Performs an ad-hoc request for the external temperature in degrees celsius. + * @param vin -Performs an ad-hoc request for the Vehicle identification number + * @param prndl -Performs an ad-hoc request for PRNDL data that houses the selected gear. + * @param tirePressure -Performs an ad-hoc request for the TireStatus data containing status and pressure of tires. + * @param odometer -Performs an ad-hoc request for Odometer data in km. + * @param beltStatus -Performs an ad-hoc request for status of the seat belts. + * @param bodyInformation -Performs an ad-hoc request for body information including power modes. + * @param deviceStatus -Performs an ad-hoc request for device status including signal and battery strength. + * @param driverBraking -Performs an ad-hoc request for the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + @Deprecated + public void getvehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure, + boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + GetVehicleData msg = new GetVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setVin(vin); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Performs a Non periodic vehicle data read request. + * Responses are captured through callback on IProxyListener. + * + * @param gps -Performs an ad-hoc request for GPS data. + * @param speed -Performs an ad-hoc request for vehicle speed data in kilometers per hour. + * @param rpm -Performs an ad-hoc request for number of revolutions per minute of the engine. + * @param fuelLevel -Performs an ad-hoc request for fuel level in the tank (percentage). + * @param fuelLevel_State -Performs an ad-hoc request for fuel level state. + * @param instantFuelConsumption -Performs an ad-hoc request for instantaneous fuel consumption in microlitres. + * @param externalTemperature -Performs an ad-hoc request for the external temperature in degrees celsius. + * @param vin -Performs an ad-hoc request for the Vehicle identification number + * @param prndl -Performs an ad-hoc request for PRNDL data that houses the selected gear. + * @param tirePressure -Performs an ad-hoc request for the TireStatus data containing status and pressure of tires. + * @param engineOilLife -Performs an ad-hoc request for Engine Oil Life data. + * @param odometer -Performs an ad-hoc request for Odometer data in km. + * @param beltStatus -Performs an ad-hoc request for status of the seat belts. + * @param bodyInformation -Performs an ad-hoc request for body information including power modes. + * @param deviceStatus -Performs an ad-hoc request for device status including signal and battery strength. + * @param driverBraking -Performs an ad-hoc request for the status of the brake pedal. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void getvehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State, + boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure, + boolean engineOilLife, boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus, + boolean driverBraking, Integer correlationID) throws SdlException + { + GetVehicleData msg = new GetVehicleData(); + msg.setGps(gps); + msg.setSpeed(speed); + msg.setRpm(rpm); + msg.setFuelLevel(fuelLevel); + msg.setFuelLevel_State(fuelLevel_State); + msg.setInstantFuelConsumption(instantFuelConsumption); + msg.setExternalTemperature(externalTemperature); + msg.setVin(vin); + msg.setPrndl(prndl); + msg.setTirePressure(tirePressure); + msg.setEngineOilLife(engineOilLife); + msg.setOdometer(odometer); + msg.setBeltStatus(beltStatus); + msg.setBodyInformation(bodyInformation); + msg.setDeviceStatus(deviceStatus); + msg.setDriverBraking(driverBraking); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + + /** + * Creates a full screen overlay containing a large block of formatted text that can be scrolled with up to 8 SoftButtons defined. + * Responses are captured through callback on IProxyListener. + * + * @param scrollableMessageBody -Body of text that can include newlines and tabs. + * @param timeout -App defined timeout. Indicates how long of a timeout from the last action. + * @param softButtons -App defined SoftButtons. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void scrollablemessage(@NonNull String scrollableMessageBody, Integer timeout, Vector<SoftButton> softButtons, Integer correlationID) throws SdlException + { + ScrollableMessage msg = new ScrollableMessage(scrollableMessageBody); + msg.setCorrelationID(correlationID); + msg.setTimeout(timeout); + msg.setSoftButtons(softButtons); + + sendRPCRequest(msg); + } + + + /** + * Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider. + * Responses are captured through callback on IProxyListener. + * + * @param numTicks -Number of selectable items on a horizontal axis. + * @param position -Initial position of slider control (cannot exceed numTicks). + * @param sliderHeader -Text header to display. + * @param sliderFooter - Text footer to display (meant to display min/max threshold descriptors). + * @param timeout -App defined timeout. Indicates how long of a timeout from the last action. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void slider(@NonNull Integer numTicks, @NonNull Integer position, @NonNull String sliderHeader, Vector<String> sliderFooter, Integer timeout, Integer correlationID) throws SdlException + { + Slider msg = new Slider(numTicks, position, sliderHeader); + msg.setCorrelationID(correlationID); + msg.setSliderFooter(sliderFooter); + msg.setTimeout(timeout); + + sendRPCRequest(msg); + } + + /** + * Responses are captured through callback on IProxyListener. + * + * @param language requested SDL voice engine (VR+TTS) language registration + * @param hmiDisplayLanguage request display language registration. + * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void changeregistration(@NonNull Language language, @NonNull Language hmiDisplayLanguage, Integer correlationID) throws SdlException + { + ChangeRegistration msg = new ChangeRegistration(language, hmiDisplayLanguage); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile device. + * Responses are captured through callback on IProxyListener. + * + * @param is - The input stream of byte data that putFileStream will read from + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of the file. + * A value greater than zero is used for resuming partial data chunks. + * @param iLength - The total length of the file being sent. + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(InputStream, String, Long, Long) + */ + @SuppressWarnings("unused") + @Deprecated + public void putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(iOffset); + msg.setLength(iLength); + + startRPCStream(is, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param inputStream The input stream of byte data that will be read from. + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param length The total length of the file being sent. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length) throws SdlException { + PutFile msg = new PutFile(fileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(offset); + msg.setLength(length); + + startRPCStream(inputStream, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile device. + * Responses are captured through callback on IProxyListener. + * + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file. + * A value greater than zero is used for resuming partial data chunks. + * @param iLength - The total length of the file being sent. + * + * @return OutputStream - The output stream of byte data that is written to by the app developer + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(String, Long, Long) + */ + @SuppressWarnings("unused") + @Deprecated + public OutputStream putFileStream(@NonNull String sdlFileName, Integer iOffset, Integer iLength) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(iOffset); + msg.setLength(iLength); + + return startRPCStream(msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param length The total length of the file being sent. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length) throws SdlException { + PutFile msg = new PutFile(fileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(offset); + msg.setLength(length); + + return startRPCStream(msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile device. + * Responses are captured through callback on IProxyListener. + * + * @param is - The input stream of byte data that PutFileStream will read from + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of the file. + * A value greater than zero is used for resuming partial data chunks. + * @param iLength - The total length of the file being sent. + * @param fileType - The selected file type -- see the FileType enumeration for details + * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles. + * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system. + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener) + */ + @SuppressWarnings("unused") + @Deprecated + public void putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, fileType); + msg.setCorrelationID(10000); + msg.setPersistentFile(bPersistentFile); + msg.setSystemFile(bSystemFile); + msg.setOffset(iOffset); + msg.setLength(iLength); + + startRPCStream(is, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param inputStream The input stream of byte data that will be read from. + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param length The total length of the file being sent. + * @param fileType The selected file type. See the {@link FileType} enum for + * details. + * @param isPersistentFile Indicates if the file is meant to persist between + * sessions / ignition cycles. + * @param isSystemFile Indicates if the file is meant to be passed through + * core to elsewhere in the system. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException { + PutFile msg = new PutFile(fileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(offset); + msg.setLength(length); + msg.setOnPutFileUpdateListener(cb); + startRPCStream(inputStream, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile device. + * Responses are captured through callback on IProxyListener. + * + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file. + * A value greater than zero is used for resuming partial data chunks. + * @param iLength - The total length of the file being sent. + * @param fileType - The selected file type -- see the FileType enumeration for details + * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles. + * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system. + * @return OutputStream - The output stream of byte data that is written to by the app developer + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener) + */ + @SuppressWarnings("unused") + @Deprecated + public OutputStream putFileStream(@NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, fileType); + msg.setCorrelationID(10000); + msg.setPersistentFile(bPersistentFile); + msg.setSystemFile(bSystemFile); + msg.setOffset(iOffset); + msg.setLength(iLength); + + return startRPCStream(msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param length The total length of the file being sent. + * @param fileType The selected file type. See the {@link FileType} enum for + * details. + * @param isPersistentFile Indicates if the file is meant to persist between + * sessions / ignition cycles. + * @param isSystemFile Indicates if the file is meant to be passed through + * core to elsewhere in the system. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public OutputStream putFileStream(@NonNull String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException { + PutFile msg = new PutFile(fileName, FileType.BINARY); + msg.setCorrelationID(10000); + msg.setSystemFile(true); + msg.setOffset(offset); + msg.setLength(length); + msg.setOnPutFileUpdateListener(cb); + + return startRPCStream(msg); + } + + /** + * Used to push a stream of putfile RPC's containing binary data from a mobile device to the module. + * Responses are captured through callback on IProxyListener. + * + * @param sPath - The physical file path on the mobile device. + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file. + * A value greater than zero is used for resuming partial data chunks. + * @param fileType - The selected file type -- see the FileType enumeration for details + * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles. + * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system. + * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse. + * @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(String, String, Long, FileType, Boolean, Boolean, Boolean, Integer, OnPutFileUpdateListener) + */ + @SuppressWarnings("unused") + @Deprecated + public RPCStreamController putFileStream(String sPath, @NonNull String sdlFileName, Integer iOffset, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, fileType); + msg.setCorrelationID(iCorrelationID); + msg.setPersistentFile(bPersistentFile); + msg.setSystemFile(bSystemFile); + msg.setOffset(iOffset); + msg.setLength(0); + + return startPutFileStream(sPath, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param path The physical file path on the mobile device. + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param fileType The selected file type. See the {@link FileType} enum for + * details. + * @param isPersistentFile Indicates if the file is meant to persist between + * sessions / ignition cycles. + * @param isSystemFile Indicates if the file is meant to be passed through + * core to elsewhere in the system. + * @param correlationId A unique id that correlates each RPCRequest and + * RPCResponse. + * @return RPCStreamController If the putFileStream was not started + * successfully null is returned, otherwise a valid object reference is + * returned . + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public RPCStreamController putFileStream(String path, @NonNull String fileName, Long offset, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId, OnPutFileUpdateListener cb ) throws SdlException { + PutFile msg = new PutFile(fileName, fileType); + msg.setCorrelationID(correlationId); + msg.setPersistentFile(isPersistentFile); + msg.setSystemFile(isSystemFile); + msg.setOffset(offset); + msg.setLength(0L); + msg.setPayloadProtected(isPayloadProtected); + msg.setOnPutFileUpdateListener(cb); + + return startPutFileStream(path,msg); + } + + /** + * Used to push a stream of putfile RPC's containing binary data from a mobile device to the module. + * Responses are captured through callback on IProxyListener. + * + * @param is - The input stream of byte data that putFileStream will read from. + * @param sdlFileName - The file reference name used by the putFile RPC. + * @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of a file. + * A value greater than zero is used for resuming partial data chunks. + * @param fileType - The selected file type -- see the FileType enumeration for details + * @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles. + * @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system. + * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse. + * @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned + * @throws SdlException if an unrecoverable error is encountered + * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, Boolean, Integer) + */ + @SuppressWarnings("unused") + @Deprecated + public RPCStreamController putFileStream(InputStream is, @NonNull String sdlFileName, Integer iOffset, Integer iLength, @NonNull FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, fileType); + msg.setCorrelationID(iCorrelationID); + msg.setPersistentFile(bPersistentFile); + msg.setSystemFile(bSystemFile); + msg.setOffset(iOffset); + msg.setLength(iLength); + + return startPutFileStream(is, msg); + } + + /** + * Used to push a binary stream of file data onto the module from a mobile + * device. Responses are captured through callback on IProxyListener. + * + * @param inputStream The input stream of byte data that will be read from. + * @param fileName The SDL file reference name used by the RPC. + * @param offset The data offset in bytes. A value of zero is used to + * indicate data starting from the beginning of the file and a value greater + * than zero is used for resuming partial data chunks. + * @param length The total length of the file being sent. + * @param fileType The selected file type. See the {@link FileType} enum for + * details. + * @param isPersistentFile Indicates if the file is meant to persist between + * sessions / ignition cycles. + * @param isSystemFile Indicates if the file is meant to be passed through + * core to elsewhere in the system. + * @param correlationId A unique id that correlates each RPCRequest and + * RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public RPCStreamController putFileStream(InputStream inputStream, @NonNull String fileName, Long offset, Long length, @NonNull FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId) throws SdlException { + PutFile msg = new PutFile(fileName, fileType); + msg.setCorrelationID(correlationId); + msg.setPersistentFile(isPersistentFile); + msg.setSystemFile(isSystemFile); + msg.setOffset(offset); + msg.setLength(length); + msg.setPayloadProtected(isPayloadProtected); + + return startPutFileStream(inputStream, msg); + } + + /** + * + * Used to end an existing putFileStream that was previously initiated with any putFileStream method. + * + */ + @SuppressWarnings("unused") + public void endPutFileStream() + { + endRPCStream(); + } + + + /** + * Used to push a binary data onto the SDL module from a mobile device, such as icons and album art. Not supported on first generation SDL vehicles. + * Responses are captured through callback on IProxyListener. + * + * @param sdlFileName -File reference name. + * @param fileType -Selected file type. + * @param persistentFile -Indicates if the file is meant to persist between sessions / ignition cycles. + * @param fileData byte array of data of the file that is to be sent + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void putfile(@NonNull String sdlFileName, @NonNull FileType fileType, Boolean persistentFile, byte[] fileData, Integer correlationID) throws SdlException + { + PutFile msg = new PutFile(sdlFileName, fileType); + msg.setCorrelationID(correlationID); + msg.setPersistentFile(persistentFile); + msg.setBulkData(fileData); + + sendRPCRequest(msg); + } + + /** + * Used to delete a file resident on the SDL module in the app's local cache. Not supported on first generation SDL vehicles. + * Responses are captured through callback on IProxyListener. + * + * @param sdlFileName -File reference name. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void deletefile(@NonNull String sdlFileName, Integer correlationID) throws SdlException + { + DeleteFile msg = new DeleteFile(sdlFileName); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Requests the current list of resident filenames for the registered app. Not supported on first generation SDL vehicles. + * Responses are captured through callback on IProxyListener. + * + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void listfiles(Integer correlationID) throws SdlException + { + ListFiles msg = new ListFiles(); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Used to set existing local file on SDL as the app's icon. Not supported on first generation SDL vehicles. + * Responses are captured through callback on IProxyListener. + * + * @param sdlFileName -File reference name. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setappicon(@NonNull String sdlFileName, Integer correlationID) throws SdlException + { + SetAppIcon msg = new SetAppIcon(sdlFileName); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Set an alternate display layout. If not sent, default screen for given platform will be shown. + * Responses are captured through callback on IProxyListener. + * + * @param displayLayout -Predefined or dynamically created screen layout. + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setdisplaylayout(@NonNull String displayLayout, Integer correlationID) throws SdlException + { + SetDisplayLayout msg = new SetDisplayLayout(displayLayout); + msg.setCorrelationID(correlationID); + + sendRPCRequest(msg); + } + + /** + * Set an alternate display layout. If not sent, default screen for given platform will be shown. + * Responses are captured through callback on IProxyListener. + * + * @param displayLayout -Predefined or dynamically created screen layout. + * @param dayColorScheme a TemplateColorScheme object representing the colors that will be used for day color scheme + * @param nightColorScheme a TemplateColorScheme object representing the colors that will be used for night color scheme + * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse. + * @throws SdlException if an unrecoverable error is encountered + */ + @SuppressWarnings("unused") + public void setdisplaylayout(String displayLayout, TemplateColorScheme dayColorScheme, TemplateColorScheme nightColorScheme, Integer correlationID) throws SdlException + { + SetDisplayLayout msg = new SetDisplayLayout(displayLayout); + msg.setCorrelationID(correlationID); + msg.setDayColorScheme(dayColorScheme); + msg.setNightColorScheme(nightColorScheme); + sendRPCRequest(msg); + } + + /** + * Gets the SystemCapabilityManager. <br> + * @return a SystemCapabilityManager object + */ + public SystemCapabilityManager getSystemCapabilityManager() { + return _systemCapabilityManager; + } + + @SuppressWarnings("unused") + public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType) { + return _systemCapabilityManager != null && _systemCapabilityManager.isCapabilitySupported(systemCapabilityType); + } + + @SuppressWarnings("unused") + public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener){ + if(_systemCapabilityManager != null){ + _systemCapabilityManager.getCapability(systemCapabilityType, scListener); + } + } + + @SuppressWarnings("unused") + public Object getCapability(SystemCapabilityType systemCapabilityType){ + if(_systemCapabilityManager != null ){ + return _systemCapabilityManager.getCapability(systemCapabilityType); + }else{ + return null; + } + } + + /** + * Add a listener to be called whenever a new capability is retrieved + * @param systemCapabilityType Type of capability desired + * @param listener callback to execute upon retrieving capability + */ + public void addOnSystemCapabilityListener(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener listener) { + if(_systemCapabilityManager != null){ + _systemCapabilityManager.addOnSystemCapabilityListener(systemCapabilityType, listener); + } + } + + /** + * Remove an OnSystemCapabilityListener that was previously added + * @param systemCapabilityType Type of capability + * @param listener the listener that should be removed + */ + public boolean removeOnSystemCapabilityListener(final SystemCapabilityType systemCapabilityType, final OnSystemCapabilityListener listener){ + if(_systemCapabilityManager != null){ + return _systemCapabilityManager.removeOnSystemCapabilityListener(systemCapabilityType, listener); + } + return false; + } + + /* ******************* END Public Helper Methods *************************/ + + /** + * Gets type of transport currently used by this SdlProxy. + * + * @return One of TransportType enumeration values. + * + * @see TransportType + */ + @SuppressWarnings("unused") + public TransportType getCurrentTransportType() throws IllegalStateException { + if (sdlSession == null) { + throw new IllegalStateException("Incorrect state of SdlProxyBase: Calling for getCurrentTransportType() while connection is not initialized"); + } + + return sdlSession.getCurrentTransportType(); + } + + public void setSdlSecurityClassList(List<Class<? extends SdlSecurityBase>> list) { + _secList = list; + } + + private void setSdlSecurity(SdlSecurityBase sec) { + if (sdlSession != null) + { + sdlSession.setSdlSecurity(sec); + } + } + + /** + * Sets the minimum protocol version that will be permitted to connect. + * If the protocol version of the head unit connected is below this version, + * the app will disconnect with an EndService protocol message and will not register. + * @param minimumProtocolVersion + */ + public void setMinimumProtocolVersion(Version minimumProtocolVersion){ + this.minimumProtocolVersion = minimumProtocolVersion; + } + + /** + * The minimum RPC version that will be permitted to connect. + * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. + * @param minimumRPCVersion + */ + public void setMinimumRPCVersion(Version minimumRPCVersion){ + this.minimumRPCVersion = minimumRPCVersion; + } + + @SuppressWarnings("unused") + public boolean isServiceTypeProtected(SessionType sType) { + return sdlSession != null && sdlSession.isServiceProtected(sType); + + } + + + public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener){ + if(serviceType != null && sdlSession != null && sdlServiceListener != null){ + sdlSession.addServiceListener(serviceType, sdlServiceListener); + } + } + + public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener){ + if(serviceType != null && sdlSession != null && sdlServiceListener != null){ + sdlSession.removeServiceListener(serviceType, sdlServiceListener); + } + } + + @SuppressWarnings("unused") + public VideoStreamingParameters getAcceptedVideoParams(){ + return sdlSession.getAcceptedVideoParams(); + } + + public IProxyListenerBase getProxyListener() + { + return _proxyListener; + } + + @SuppressWarnings("unused") + public String getAppName() + { + return _applicationName; + } + + @SuppressWarnings("unused") + public String getNgnAppName() + { + return _ngnMediaScreenAppName; + } + + @SuppressWarnings("unused") + public String getAppID() + { + return _appID; + } + @SuppressWarnings("unused") + public DeviceInfo getDeviceInfo() + { + return deviceInfo; + } + @SuppressWarnings("unused") + public long getInstanceDT() + { + return instanceDateTime; + } + @SuppressWarnings("unused") + public void setConnectionDetails(String sDetails) + { + sConnectionDetails = sDetails; + } + @SuppressWarnings("unused") + public String getConnectionDetails() + { + return sConnectionDetails; + } + //for testing only + @SuppressWarnings("unused") + public void setPoliciesURL(String sText) + { + sPoliciesURL = sText; + } + //for testing only + public String getPoliciesURL() + { + return sPoliciesURL; + } + + /** + * Tells developer whether or not their app icon has been resumed on core. + * @return boolean - true if icon was resumed, false if not + * @throws SdlException if proxy is disposed or app is not registered + */ + public boolean getIconResumed() throws SdlException { + // Test if proxy has been disposed + if (_proxyDisposed) { + throw new SdlException("This object has been disposed, it is no long capable of executing methods.", SdlExceptionCause.SDL_PROXY_DISPOSED); + } + + // Test SDL availability + if (!_appInterfaceRegisterd) { + throw new SdlException("SDL is not connected. Unable to determine if app icon was resumed.", SdlExceptionCause.SDL_UNAVAILABLE); + } + return _iconResumed; + } + + /** + * Method to retrieve the RegisterAppInterface Response message that was sent back from the + * module. It contains various attributes about the connected module and can be used to adapt + * to different module types and their supported features. + * + * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet + * registered with the module. + */ + public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ + return this.raiResponse; + } + + /** + * Get the current OnHMIStatus + * @return OnHMIStatus object represents the current OnHMIStatus + */ + public OnHMIStatus getCurrentHMIStatus(){ + return lastHmiStatus; + } + + /** + * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC + * service from the module. For example, this should be used to login to a user account. + * @return the string representation of the auth token + */ + public String getAuthToken(){ + return this.authToken; + } + + /** + * VideoStreamingManager houses all the elements needed to create a scoped, streaming manager for video projection. It is only a private, instance + * dependant class at the moment until it can become public. Once the class is public and API defined, it will be moved into the SdlSession class + */ + @TargetApi(19) + private class VideoStreamingManager implements ISdlServiceListener{ + Context context; + ISdl internalInterface; + volatile VirtualDisplayEncoder encoder; + private Class<? extends SdlRemoteDisplay> remoteDisplayClass = null; + SdlRemoteDisplay remoteDisplay; + IVideoStreamListener streamListener; + float[] touchScalar = {1.0f,1.0f}; //x, y + private HapticInterfaceManager hapticManager; + SdlMotionEvent sdlMotionEvent = null; + VideoStreamingParameters videoStreamingParameters; + + public VideoStreamingManager(Context context,ISdl iSdl){ + this.context = context; + this.internalInterface = iSdl; + encoder = new VirtualDisplayEncoder(); + internalInterface.addServiceListener(SessionType.NAV,this); + //Take care of the touch events + internalInterface.addOnRPCNotificationListener(FunctionID.ON_TOUCH_EVENT, new OnRPCNotificationListener() { + @Override + public void onNotified(RPCNotification notification) { + if (notification != null && remoteDisplay != null) { + List<MotionEvent> events = convertTouchEvent((OnTouchEvent) notification); + if (events != null && !events.isEmpty()) { + for (MotionEvent ev : events) { + remoteDisplay.handleMotionEvent(ev); + } + } + } + } + }); + } + + /** + * Starts the video service, caches the supplied params and prepares for the stream to start. + * @param remoteDisplayClass the extension of SdlRemoteDisplay that will be streamed + * @param parameters desired video streaming params + * @param encrypted if the service is to be encrypted or not + */ + public void startVideoStreaming(Class<? extends SdlRemoteDisplay> remoteDisplayClass, VideoStreamingParameters parameters, boolean encrypted){ + this.remoteDisplayClass = remoteDisplayClass; + this.videoStreamingParameters = parameters; + //Make sure the service is started, allows multi transports to connect and register without timing out + internalInterface.startVideoService(parameters, encrypted); + //After this, look to the + } + + /** + * The video service should already be started at this point. Once called, it will start + * the encoders and fire up the remote display supplied by the user + * @param parameters + * @param encrypted + */ + private void startStream(VideoStreamingParameters parameters, boolean encrypted){ + //Start the service first + //streamListener = startVideoStream(encrypted,parameters);d + streamListener = sdlSession.startVideoStream(); + if(streamListener == null){ + Log.e(TAG, "Error starting video service"); + return; + } + VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING); + if(capability != null && capability.getIsHapticSpatialDataSupported()){ + hapticManager = new HapticInterfaceManager(internalInterface); + } + + try { + encoder.init(context, streamListener, parameters); + //We are all set so we can start streaming at at this point + encoder.start(); + //Encoder should be up and running + createRemoteDisplay(encoder.getVirtualDisplay()); + } catch (Exception e) { + e.printStackTrace(); + } + Log.d(TAG, parameters.toString()); + } + + public void stopStreaming(){ + if(remoteDisplay!=null){ + remoteDisplay.stop(); + remoteDisplay = null; + } + if(encoder!=null){ + encoder.shutDown(); + } + if(internalInterface!=null){ + internalInterface.stopVideoService(); + } + } + + public void dispose(){ + stopStreaming(); + internalInterface.removeServiceListener(SessionType.NAV,this); + } + + private void createRemoteDisplay(final Display disp){ + try{ + if (disp == null){ + return; + } + + // Dismiss the current presentation if the display has changed. + if (remoteDisplay != null && remoteDisplay.getDisplay() != disp) { + remoteDisplay.dismissPresentation(); + } + + FutureTask<Boolean> fTask = new FutureTask<Boolean>( new SdlRemoteDisplay.Creator(context, disp, remoteDisplay, remoteDisplayClass, new SdlRemoteDisplay.Callback(){ + @Override + public void onCreated(final SdlRemoteDisplay remoteDisplay) { + //Remote display has been created. + //Now is a good time to do parsing for spatial data + SdlProxyBase.VideoStreamingManager.this.remoteDisplay = remoteDisplay; + if(hapticManager != null) { + remoteDisplay.getMainView().post(new Runnable() { + @Override + public void run() { + hapticManager.refreshHapticData(remoteDisplay.getMainView()); + } + }); + } + //Get touch scalars + ImageResolution resolution = null; + if(protocolVersion!= null && protocolVersion.getMajor()>=5){ //At this point we should already have the capability + VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING); + if (capability != null) { + resolution = capability.getPreferredResolution(); + } + } + + if(resolution == null){ //Either the protocol version is too low to access video streaming caps, or they were null + DisplayCapabilities dispCap = (DisplayCapabilities) internalInterface.getCapability(SystemCapabilityType.DISPLAY); + if (dispCap != null) { + resolution = (dispCap.getScreenParams().getImageResolution()); + } + } + + if(resolution != null){ + DisplayMetrics displayMetrics = new DisplayMetrics(); + disp.getMetrics(displayMetrics); + touchScalar[0] = ((float)displayMetrics.widthPixels) / resolution.getResolutionWidth(); + touchScalar[1] = ((float)displayMetrics.heightPixels) / resolution.getResolutionHeight(); + } + + } + + @Override + public void onInvalidated(final SdlRemoteDisplay remoteDisplay) { + //Our view has been invalidated + //A good time to refresh spatial data + if(hapticManager != null) { + remoteDisplay.getMainView().post(new Runnable() { + @Override + public void run() { + hapticManager.refreshHapticData(remoteDisplay.getMainView()); + } + }); + } + } + } )); + Thread showPresentation = new Thread(fTask); + + showPresentation.start(); + } catch (Exception ex) { + Log.e(TAG, "Unable to create Virtual Display."); + } + } + + @Override + public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { + if(SessionType.NAV.equals(type) && session != null ){ + DebugTool.logInfo("Video service has been started. Starting video stream from proxy"); + if(session.getAcceptedVideoParams() != null){ + videoStreamingParameters = session.getAcceptedVideoParams(); + } + startStream(videoStreamingParameters, isEncrypted); + } + } + + @Override + public void onServiceEnded(SdlSession session, SessionType type) { + if(SessionType.NAV.equals(type)){ + if(remoteDisplay!=null){ + stopStreaming(); + } + } + } + + @Override + public void onServiceError(SdlSession session, SessionType type, String reason) { + + } + + private List<MotionEvent> convertTouchEvent(OnTouchEvent onTouchEvent) { + List<MotionEvent> motionEventList = new ArrayList<MotionEvent>(); + + List<TouchEvent> touchEventList = onTouchEvent.getEvent(); + if (touchEventList == null || touchEventList.size() == 0) return null; + + TouchType touchType = onTouchEvent.getType(); + if (touchType == null) { + return null; + } + + if (sdlMotionEvent == null) { + if (touchType == TouchType.BEGIN) { + sdlMotionEvent = new SdlMotionEvent(); + } else { + return null; + } + } + + SdlMotionEvent.Pointer pointer; + MotionEvent motionEvent; + + for (TouchEvent touchEvent : touchEventList) { + if (touchEvent == null || touchEvent.getId() == null) { + continue; + } + + List<TouchCoord> touchCoordList = touchEvent.getTouchCoordinates(); + if (touchCoordList == null || touchCoordList.size() == 0) { + continue; + } + + TouchCoord touchCoord = touchCoordList.get(touchCoordList.size() - 1); + if (touchCoord == null) { + continue; + } + + int motionEventAction = sdlMotionEvent.getMotionEventAction(touchType, touchEvent); + long downTime = sdlMotionEvent.downTime; + long eventTime = sdlMotionEvent.eventTime; + pointer = sdlMotionEvent.getPointerById(touchEvent.getId()); + if (pointer != null) { + pointer.setCoords(touchCoord.getX() * touchScalar[0], touchCoord.getY() * touchScalar[1]); + } + + MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[sdlMotionEvent.pointers.size()]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[sdlMotionEvent.pointers.size()]; + + for (int i = 0; i < sdlMotionEvent.pointers.size(); i++) { + pointerProperties[i] = new MotionEvent.PointerProperties(); + pointerProperties[i].id = sdlMotionEvent.getPointerByIndex(i).id; + pointerProperties[i].toolType = MotionEvent.TOOL_TYPE_FINGER; + + pointerCoords[i] = new MotionEvent.PointerCoords(); + pointerCoords[i].x = sdlMotionEvent.getPointerByIndex(i).x; + pointerCoords[i].y = sdlMotionEvent.getPointerByIndex(i).y; + pointerCoords[i].orientation = 0; + pointerCoords[i].pressure = 1.0f; + pointerCoords[i].size = 1; + } + + motionEvent = MotionEvent.obtain(downTime, eventTime, motionEventAction, + sdlMotionEvent.pointers.size(), pointerProperties, pointerCoords, 0, 0, 1, + 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); + motionEventList.add(motionEvent); + + if (motionEventAction == MotionEvent.ACTION_UP || motionEventAction == MotionEvent.ACTION_CANCEL) { + //If the motion event should be finished we should clear our reference + sdlMotionEvent.pointers.clear(); + sdlMotionEvent = null; + break; + } else if ((motionEventAction & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) { + sdlMotionEvent.removePointerById(touchEvent.getId()); + } + } + + return motionEventList; + } + } + + /** + * Keeps track of the current motion event for VPM + */ + private static class SdlMotionEvent { + class Pointer { + int id; + float x; + float y; + + Pointer(int id) { + this.id = id; + this.x = 0.0f; + this.y = 0.0f; + } + + void setCoords(float x, float y) { + this.x = x; + this.y = y; + } + } + + private CopyOnWriteArrayList<Pointer> pointers = new CopyOnWriteArrayList<>(); + private long downTime; + private long downTimeOnHMI; + private long eventTime; + + SdlMotionEvent() { + downTimeOnHMI = 0; + } + + /** + * Handles the SDL Touch Event to keep track of pointer status and returns the appropriate + * Android MotionEvent according to this events status + * + * @param touchType The SDL TouchType that was received from the module + * @param touchEvent The SDL TouchEvent that was received from the module + * @return the correct native Android MotionEvent action to dispatch + */ + synchronized int getMotionEventAction(TouchType touchType, TouchEvent touchEvent) { + eventTime = 0; + int motionEventAction = -1; + switch (touchType) { + case BEGIN: + if (pointers.size() == 0) { + //The motion event has just begun + motionEventAction = MotionEvent.ACTION_DOWN; + downTime = SystemClock.uptimeMillis(); + downTimeOnHMI = touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1); + eventTime = downTime; + } else { + motionEventAction = MotionEvent.ACTION_POINTER_DOWN | pointers.size() << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI; + } + pointers.add(new Pointer(touchEvent.getId())); + break; + case MOVE: + motionEventAction = MotionEvent.ACTION_MOVE; + eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI; + break; + case END: + if(pointers.size() <= 1){ + //The motion event has just ended + motionEventAction = MotionEvent.ACTION_UP; + } else { + int pointerIndex = pointers.indexOf(getPointerById(touchEvent.getId())); + if (pointerIndex != -1) { + motionEventAction = MotionEvent.ACTION_POINTER_UP | pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT; + } else { + motionEventAction = MotionEvent.ACTION_UP; + } + } + eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI; + break; + case CANCEL: + //Assuming this cancels the entire event + motionEventAction = MotionEvent.ACTION_CANCEL; + eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI; + break; + default: + break; + } + return motionEventAction; + } + + Pointer getPointerById(int id) { + if (pointers != null && !pointers.isEmpty()) { + for (Pointer pointer : pointers) { + if (pointer.id == id) { + return pointer; + } + } + } + return null; + } + + Pointer getPointerByIndex(int index) { + return pointers.get(index); + } + + void removePointerById(int id) { + pointers.remove(getPointerById(id)); + } + } + +} // end-class diff --git a/android/sdl_android/src/main/res/values/strings.xml b/android/sdl_android/src/main/res/values/strings.xml index 1d55ec24d..f74ce713b 100644 --- a/android/sdl_android/src/main/res/values/strings.xml +++ b/android/sdl_android/src/main/res/values/strings.xml @@ -3,4 +3,5 @@ <string name="lockscreen_text">Locked for your safety</string> <string name="lockscreen_image_description">SDL Icon</string> <string name="lockscreen_device_image_description">Device Icon</string> + <string name="default_lockscreen_warning_message">Swipe down to dismiss, acknowledging that you are not the driver.</string> </resources>
\ No newline at end of file diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java index d0d748773..04b090f8c 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java @@ -344,6 +344,23 @@ abstract class BaseScreenManager extends BaseSubManager { } /** + * Sets the title of the new template that will be displayed. + * Sending an empty String "" will clear the field + * @param templateTitle the title of the new template that will be displayed. Maxlength: 100. + */ + public void setTemplateTitle(String templateTitle){ + this.textAndGraphicManager.setTemplateTitle(templateTitle); + } + + /** + * Gets the title of the new template that will be displayed + * @return templateTitle - String value that represents the title of the new template that will be displayed + */ + public String getTemplateTitle(){ + return this.textAndGraphicManager.getTemplateTitle(); + } + + /** * Set softButtonObjects list and upload the images to the head unit * @param softButtonObjects the list of the SoftButtonObject values that should be displayed on the head unit */ @@ -393,6 +410,8 @@ abstract class BaseScreenManager extends BaseSubManager { this.voiceCommandManager.setVoiceCommands(voiceCommands); } + // MENUS + /** * The list of currently set menu cells * @return a List of the currently set menu cells @@ -419,7 +438,6 @@ abstract class BaseScreenManager extends BaseSubManager { } /** - * * @return The currently set DynamicMenuUpdatesMode. It defaults to ON_WITH_COMPAT_MODE if not set. */ public DynamicMenuUpdatesMode getDynamicMenuUpdatesMode(){ @@ -427,6 +445,25 @@ abstract class BaseScreenManager extends BaseSubManager { } /** + * Requires SDL RPC Version 6.0.0 or greater + * Opens the Main Menu. + * @return boolean success / failure - whether the request was able to be sent + */ + public boolean openMenu(){ + return this.menuManager.openMenu(); + } + + /** + * Requires SDL RPC Version 6.0.0 or greater + * Opens a subMenu. The cell you pass in must be constructed with {@link MenuCell(String,SdlArtwork,List)} + * @param cell - A <Strong>SubMenu</Strong> cell whose sub menu you wish to open + * @return boolean success / failure - whether the request was able to be sent + */ + public boolean openSubMenu(@NonNull MenuCell cell){ + return this.menuManager.openSubMenu(cell); + } + + /** * The main menu layout. See available menu layouts on DisplayCapabilities.menuLayoutsAvailable. Defaults to LIST. * @param menuConfiguration - The default menuConfiguration */ diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java index 45f1dad0b..d4ca4321e 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java @@ -90,7 +90,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { private OnSystemCapabilityListener onDisplayCapabilitiesListener; private SdlArtwork primaryGraphic, secondaryGraphic; private TextAlignment textAlignment; - private String textField1, textField2, textField3, textField4, mediaTrackTextField; + private String textField1, textField2, textField3, textField4, mediaTrackTextField, templateTitle; private MetadataType textField1Type, textField2Type, textField3Type, textField4Type; //Constructors @@ -128,6 +128,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { textField4 = null; textField4Type = null; mediaTrackTextField = null; + templateTitle = null; textAlignment = null; primaryGraphic = null; secondaryGraphic = null; @@ -379,6 +380,10 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { show.setMediaTrack(mediaTrackTextField); } + if (templateTitle != null){ + show.setTemplateTitle(templateTitle); + } + List<String> nonNullFields = findValidMainTextFields(); if (nonNullFields.isEmpty()){ return show; @@ -602,6 +607,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { newShow.setMainField2(show.getMainField2()); newShow.setMainField3(show.getMainField3()); newShow.setMainField4(show.getMainField4()); + newShow.setTemplateTitle(show.getTemplateTitle()); return newShow; } @@ -613,6 +619,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { newShow.setMainField3(""); newShow.setMainField4(""); newShow.setMediaTrack(""); + newShow.setTemplateTitle(""); return newShow; } @@ -637,6 +644,9 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { if (show.getMainField4() != null){ currentScreenData.setMainField4(show.getMainField4()); } + if (show.getTemplateTitle() != null){ + currentScreenData.setTemplateTitle(show.getTemplateTitle()); + } if (show.getMediaTrack() != null){ currentScreenData.setMediaTrack(show.getMediaTrack()); } @@ -890,6 +900,19 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { return textField4Type; } + void setTemplateTitle(String templateTitle){ + this.templateTitle = templateTitle; + if (!batchingUpdates){ + sdlUpdate(null); + }else{ + isDirty = true; + } + } + + String getTemplateTitle(){ + return templateTitle; + } + void setPrimaryGraphic(SdlArtwork primaryGraphic){ this.primaryGraphic = primaryGraphic; if (!batchingUpdates){ 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 074f89947..4ac5cb659 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 @@ -80,17 +80,15 @@ class CheckChoiceVROptionalOperation implements Runnable { isVROptional = true; deleteTestChoiceSet(); }else{ + DebugTool.logWarning("Head unit doesn't support choices with no VR."); sendTestChoiceWithVR(); } } @Override public void onError(int correlationId, Result resultCode, String info){ - DebugTool.logError("There was an error in the check choice vr optional operation. Send test choice with no VR failed. Error: " + info + " resultCode: " + resultCode); - isVROptional = false; - if (checkChoiceVROptionalInterface != null){ - checkChoiceVROptionalInterface.onError(info); - } + DebugTool.logWarning("Head unit doesn't support choices with no VR. Error: " + info + " resultCode: " + resultCode); + sendTestChoiceWithVR(); } }); diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java index f9be78036..faf0327f3 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java @@ -55,6 +55,7 @@ import com.smartdevicelink.proxy.rpc.MenuParams; import com.smartdevicelink.proxy.rpc.OnCommand; import com.smartdevicelink.proxy.rpc.OnHMIStatus; import com.smartdevicelink.proxy.rpc.SdlMsgVersion; +import com.smartdevicelink.proxy.rpc.ShowAppMenu; import com.smartdevicelink.proxy.rpc.SetGlobalProperties; import com.smartdevicelink.proxy.rpc.enums.DisplayType; import com.smartdevicelink.proxy.rpc.enums.HMILevel; @@ -256,54 +257,136 @@ abstract class BaseMenuManager extends BaseSubManager { return this.dynamicMenuUpdatesMode; } - /** - * This method is called via the screen manager to set the menuConfiguration. - * This will be used when a menu item with sub-cells has a null value for menuConfiguration - * @param menuConfiguration - The default menuConfiguration - */ - public void setMenuConfiguration(@NonNull final MenuConfiguration menuConfiguration) { - - if (sdlMsgVersion == null) { - DebugTool.logError("SDL Message Version is null. Cannot set Menu Configuration"); - return; - } - - if (sdlMsgVersion.getMajorVersion() < 6){ - DebugTool.logWarning("Menu configurations is only supported on head units with RPC spec version 6.0.0 or later. Currently connected head unit RPC spec version is: "+sdlMsgVersion.getMajorVersion() + "." + sdlMsgVersion.getMinorVersion()+ "." +sdlMsgVersion.getPatchVersion()); - return; - } - - if (currentHMILevel == null || currentHMILevel.equals(HMILevel.HMI_NONE) || currentSystemContext.equals(SystemContext.SYSCTXT_MENU)){ - // We are in NONE or the menu is in use, bail out of here - DebugTool.logError("Could not set main menu configuration, HMI level: "+currentHMILevel+", required: 'Not-NONE', system context: "+currentSystemContext+", required: 'Not MENU'"); - return; - } - - // In the future, when the manager is switched to use queues, the menuConfiguration should be set when SetGlobalProperties response is received - this.menuConfiguration = menuConfiguration; - - SetGlobalProperties setGlobalProperties = new SetGlobalProperties(); - setGlobalProperties.setMenuLayout(menuConfiguration.getMenuLayout()); - setGlobalProperties.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()){ - DebugTool.logInfo("Menu Configuration successfully set: "+ menuConfiguration.toString()); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info){ - DebugTool.logError("onError: "+ resultCode+ " | Info: "+ info ); - } - }); - internalInterface.sendRPC(setGlobalProperties); - } - - public MenuConfiguration getMenuConfiguration(){ - return this.menuConfiguration; - } - + // OPEN MENU RPCs + + /** + * Opens the Main Menu + */ + public boolean openMenu(){ + + if (sdlMsgVersion.getMajorVersion() < 6){ + DebugTool.logWarning("Menu opening is only supported on head units with RPC spec version 6.0.0 or later. Currently connected head unit RPC spec version is: "+sdlMsgVersion.getMajorVersion() + "." + sdlMsgVersion.getMinorVersion()+ "." +sdlMsgVersion.getPatchVersion()); + return false; + } + + ShowAppMenu showAppMenu = new ShowAppMenu(); + showAppMenu.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (response.getSuccess()){ + DebugTool.logInfo("Open Main Menu Request Successful"); + } else { + DebugTool.logError("Open Main Menu Request Failed"); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info){ + DebugTool.logError("Open Main Menu onError: "+ resultCode+ " | Info: "+ info); + } + }); + internalInterface.sendRPC(showAppMenu); + return true; + } + + /** + * Opens a subMenu. The cell you pass in must be constructed with {@link MenuCell(String,SdlArtwork,List)} + * @param cell - A <Strong>SubMenu</Strong> cell whose sub menu you wish to open + */ + public boolean openSubMenu(@NonNull MenuCell cell){ + + if (sdlMsgVersion.getMajorVersion() < 6){ + DebugTool.logWarning("Sub menu opening is only supported on head units with RPC spec version 6.0.0 or later. Currently connected head unit RPC spec version is: "+sdlMsgVersion.getMajorVersion() + "." + sdlMsgVersion.getMinorVersion()+ "." +sdlMsgVersion.getPatchVersion()); + return false; + } + + if (oldMenuCells == null){ + DebugTool.logError("open sub menu called, but no Menu cells have been set"); + return false; + } + // We must see if we have a copy of this cell, since we clone the objects + for (MenuCell clonedCell : oldMenuCells){ + if (clonedCell.equals(cell) && clonedCell.getCellId() != MAX_ID){ + // We've found the correct sub menu cell + sendOpenSubMenu(clonedCell.getCellId()); + return true; + } + } + return false; + } + + private void sendOpenSubMenu(Integer id){ + + ShowAppMenu showAppMenu = new ShowAppMenu(); + showAppMenu.setMenuID(id); + showAppMenu.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (response.getSuccess()){ + DebugTool.logInfo("Open Sub Menu Request Successful"); + } else { + DebugTool.logError("Open Sub Menu Request Failed"); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info){ + DebugTool.logError("Open Sub Menu onError: "+ resultCode+ " | Info: "+ info); + } + }); + + internalInterface.sendRPC(showAppMenu); + } + + // MENU CONFIG + + /** + * This method is called via the screen manager to set the menuConfiguration. + * This will be used when a menu item with sub-cells has a null value for menuConfiguration + * @param menuConfiguration - The default menuConfiguration + */ + public void setMenuConfiguration(@NonNull final MenuConfiguration menuConfiguration) { + + if (sdlMsgVersion == null) { + DebugTool.logError("SDL Message Version is null. Cannot set Menu Configuration"); + return; + } + + if (sdlMsgVersion.getMajorVersion() < 6){ + DebugTool.logWarning("Menu configurations is only supported on head units with RPC spec version 6.0.0 or later. Currently connected head unit RPC spec version is: "+sdlMsgVersion.getMajorVersion() + "." + sdlMsgVersion.getMinorVersion()+ "." +sdlMsgVersion.getPatchVersion()); + return; + } + + if (currentHMILevel == null || currentHMILevel.equals(HMILevel.HMI_NONE) || currentSystemContext.equals(SystemContext.SYSCTXT_MENU)){ + // We are in NONE or the menu is in use, bail out of here + DebugTool.logError("Could not set main menu configuration, HMI level: "+currentHMILevel+", required: 'Not-NONE', system context: "+currentSystemContext+", required: 'Not MENU'"); + return; + } + + // In the future, when the manager is switched to use queues, the menuConfiguration should be set when SetGlobalProperties response is received + this.menuConfiguration = menuConfiguration; + + SetGlobalProperties setGlobalProperties = new SetGlobalProperties(); + setGlobalProperties.setMenuLayout(menuConfiguration.getMenuLayout()); + setGlobalProperties.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + if (response.getSuccess()){ + DebugTool.logInfo("Menu Configuration successfully set: "+ menuConfiguration.toString()); + } + } + + @Override + public void onError(int correlationId, Result resultCode, String info){ + DebugTool.logError("onError: "+ resultCode+ " | Info: "+ info ); + } + }); + internalInterface.sendRPC(setGlobalProperties); + } + + public MenuConfiguration getMenuConfiguration(){ + return this.menuConfiguration; + } // UPDATING SYSTEM // ROOT MENU diff --git a/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java b/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java index 4c755e0a1..e29b42070 100644 --- a/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java +++ b/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java @@ -103,6 +103,7 @@ public enum FunctionID{ UNPUBLISH_APP_SERVICE(56, "UnpublishAppService"),
CANCEL_INTERACTION(57, "CancelInteraction"),
CLOSE_APPLICATION(58, "CloseApplication"),
+ SHOW_APP_MENU(59, "ShowAppMenu"),
// NOTIFICATIONS
ON_HMI_STATUS(32768, "OnHMIStatus"),
diff --git a/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java b/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java index b6cd9c236..4dd72f906 100644 --- a/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java +++ b/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java @@ -96,6 +96,7 @@ import com.smartdevicelink.proxy.rpc.SetDisplayLayoutResponse; import com.smartdevicelink.proxy.rpc.SetGlobalPropertiesResponse;
import com.smartdevicelink.proxy.rpc.SetInteriorVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.SetMediaClockTimerResponse;
+import com.smartdevicelink.proxy.rpc.ShowAppMenuResponse;
import com.smartdevicelink.proxy.rpc.ShowConstantTbtResponse;
import com.smartdevicelink.proxy.rpc.ShowResponse;
import com.smartdevicelink.proxy.rpc.SliderResponse;
@@ -433,11 +434,19 @@ public interface IProxyListenerBase { */
public void onCancelInteractionResponse(CancelInteractionResponse response);
- /**
- * UnpublishAppServiceResponse being called indicates that SDL has
- * responded to a request to close the application on the module.
- *
- * @param response - Contains information about the response sent from SDL.
- */
- public void onUnpublishAppServiceResponse(UnpublishAppServiceResponse response);
+ /**
+ * UnpublishAppServiceResponse being called indicates that SDL has
+ * responded to a request to close the application on the module.
+ *
+ * @param response - Contains information about the response sent from SDL.
+ */
+ public void onUnpublishAppServiceResponse(UnpublishAppServiceResponse response);
+
+ /**
+ * onShowAppMenuResponse being called indicates that SDL has
+ * responded to a request to close the application on the module.
+ *
+ * @param response - Contains information about the response sent from SDL.
+ */
+ public void onShowAppMenuResponse(ShowAppMenuResponse response);
}
\ No newline at end of file diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java index e4efe5e13..f6a328dcf 100644 --- a/base/src/main/java/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java +++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/OnDriverDistraction.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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.proxy.rpc;
import android.support.annotation.NonNull;
@@ -73,6 +73,8 @@ import java.util.Hashtable; */
public class OnDriverDistraction extends RPCNotification {
public static final String KEY_STATE = "state";
+ public static final String KEY_LOCKSCREEN_DISMISSIBLE = "lockScreenDismissalEnabled";
+ public static final String KEY_LOCKSCREEN_DISMISSIBLE_MSG = "lockScreenDismissalWarning";
/**
*Constructs a newly allocated OnDriverDistraction object
*/
@@ -107,5 +109,37 @@ public class OnDriverDistraction extends RPCNotification { */
public void setState( @NonNull DriverDistractionState state ) {
setParameters(KEY_STATE, state);
- }
+ }
+
+ /**
+ * <p>Called to set dismissible state of Lockscreen</p>
+ * @param isDismissible the Lockscreen's dismissibility
+ */
+ public void setLockscreenDismissibility(boolean isDismissible) {
+ setParameters(KEY_LOCKSCREEN_DISMISSIBLE, isDismissible);
+ }
+
+ /**
+ * <p>Called to get the dismissible state of Lockscreen</p>
+ * @return true if the Lockscreen is dismissible, false otherwise
+ */
+ public Boolean getLockscreenDismissibility() {
+ return (Boolean) getObject(Boolean.class, KEY_LOCKSCREEN_DISMISSIBLE);
+ }
+
+ /**
+ * Called to set a warning message for the lockscreen
+ * @param msg the message to be set
+ */
+ public void setLockscreenWarningMessage(String msg) {
+ setParameters(KEY_LOCKSCREEN_DISMISSIBLE_MSG, msg);
+ }
+
+ /**
+ * Called to get the lockscreen warning message
+ * @return warning message
+ */
+ public String getLockscreenWarningMessage() {
+ return (String) getObject(String.class, KEY_LOCKSCREEN_DISMISSIBLE_MSG);
+ }
}
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java index 8a536e4a9..63ce0e44b 100644 --- a/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java +++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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.proxy.rpc;
import com.smartdevicelink.protocol.enums.FunctionID;
@@ -162,6 +162,14 @@ import java.util.List; * <td><p>If omitted on supported displays, the presets will be shown as not defined.</p>Minsize: 0; Maxsize: 6</td>
* <td>SmartDeviceLink 2.0</td>
* </tr>
+ * <tr>
+ * <td>templateTitle</td>
+ * <td>String</td>
+ * <td>The title of the new template that will be displayed.</td>
+ * <td><p>How this will be displayed is dependent on the OEM design and implementation of the template..</p>Minsize: 0; Maxsize: 100</td>
+ * <td>N</td>
+ * <td>SmartDeviceLink 6.0.0</td>
+ * </tr>
*
* </table>
*<p><b>Response </b></p>
@@ -196,6 +204,8 @@ public class Show extends RPCRequest { public static final String KEY_SECONDARY_GRAPHIC = "secondaryGraphic";
public static final String KEY_SOFT_BUTTONS = "softButtons";
public static final String KEY_METADATA_TAGS = "metadataTags";
+ public static final String KEY_TEMPLATE_TITLE = "templateTitle";
+
/**
* Constructs a new Show object
*/
@@ -439,7 +449,7 @@ public class Show extends RPCRequest { * Sets the text in the track field
*
* @param mediaTrack
- * a String value disaplayed in the track field
+ * a String value displayed in the track field
* <p></p>
* <b>Notes: </b>
* <ul>
@@ -577,4 +587,29 @@ public class Show extends RPCRequest { public MetadataTags getMetadataTags() {
return (MetadataTags) getObject(MetadataTags.class, KEY_METADATA_TAGS);
}
+
+ /**
+ * Sets the title of the new template that will be displayed.
+ * How this will be displayed is dependent on the OEM design and implementation of the template.
+ * @param templateTitle the title of the new template that will be displayed
+ * <p></p>
+ * <ul>
+ * <li>Minlength: 0</li>
+ * <li>Maxlength: 100</li>
+ * </ul>
+ * @since SmartDeviceLink 6.0.0
+ */
+ public void setTemplateTitle(String templateTitle){
+ setParameters(KEY_TEMPLATE_TITLE, templateTitle);
+ }
+
+ /**
+ * Gets the title of the new template that will be displayed
+ * How this will be displayed is dependent on the OEM design and implementation of the template.
+ * @return templateTitle - String value that represents the title of the new template that will be displayed
+ * @since SmartDeviceLink 6.0.0
+ */
+ public String getTemplateTitle(){
+ return getString(KEY_TEMPLATE_TITLE);
+ }
}
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenu.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenu.java new file mode 100644 index 000000000..6c6c2e7c9 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenu.java @@ -0,0 +1,85 @@ +/* + * 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. + * + * Created by brettywhite on 7/16/19 1:44 PM + * + */ + +package com.smartdevicelink.proxy.rpc; + +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.RPCRequest; + +import java.util.Hashtable; + +public class ShowAppMenu extends RPCRequest { + + public static final String KEY_MENU_ID = "menuID"; + + /** + * Constructs a new ShowAppMenu object + */ + public ShowAppMenu() { + super(FunctionID.SHOW_APP_MENU.toString()); + } + + /** + * Constructs a new ShowAppMenu object indicated by the Hashtable parameter + * + * @param hash The Hashtable to use + */ + public ShowAppMenu(Hashtable<String, Object> hash) { + super(hash); + } + + // SETTERS AND GETTERS + + /** + * If omitted the HMI opens the apps menu. + * If set to a sub-menu ID the HMI opens the corresponding sub-menu + * previously added using `AddSubMenu`. + * @param menuID - The SubMenu ID to open + */ + public void setMenuID(Integer menuID){ + setParameters(KEY_MENU_ID, menuID); + } + + /** + * If omitted the HMI opens the apps menu. + * If set to a sub-menu ID the HMI opens the corresponding sub-menu + * previously added using `AddSubMenu`. + * @return - MenuID int + */ + public Integer getMenuID(){ + return getInteger(KEY_MENU_ID); + } + +} diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenuResponse.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenuResponse.java new file mode 100644 index 000000000..0efdc5229 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/ShowAppMenuResponse.java @@ -0,0 +1,62 @@ +/* + * 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. + * + * Created by brettywhite on 7/16/19 1:52 PM + * + */ + +package com.smartdevicelink.proxy.rpc; + +import com.smartdevicelink.protocol.enums.FunctionID; +import com.smartdevicelink.proxy.RPCResponse; + +import java.util.Hashtable; + +/** + * The response to ShowAppMenuResponse + */ +public class ShowAppMenuResponse extends RPCResponse { + /** + * Constructs a new ShowAppMenuResponse object + */ + public ShowAppMenuResponse() { + super(FunctionID.SHOW_APP_MENU.toString()); + } + + /** + * Constructs a new ShowAppMenuResponse object indicated by the Hashtable parameter + * + * @param hash The Hashtable to use + */ + public ShowAppMenuResponse(Hashtable<String, Object> hash) { + super(hash); + } +}
\ No newline at end of file diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java index f7258b933..a8fe4bd38 100644 --- a/base/src/main/java/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java +++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/enums/TextFieldName.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, 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 SmartDeviceLink Consortium, 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.proxy.rpc.enums;
/** Names of the text fields that can appear on the display.
*
@@ -154,7 +154,7 @@ public enum TextFieldName { tertiaryText,
/** Optional text to label an app menu button (for certain touchscreen platforms).
*
- */ + */
menuTitle,
/**
* Optional name / title of intended location for SendLocation.
@@ -175,11 +175,17 @@ public enum TextFieldName { */
addressLines,
/**
- * Optional hone number of intended location / establishment (if applicable) for SendLocation.
+ * Optional phone number of intended location / establishment (if applicable) for SendLocation.
*
* @since SmartDeviceLink 4.0
*/
phoneNumber,
+ /**
+ * Optional title of the template that will be displayed
+ *
+ * @since SmartDeviceLink 6.0
+ */
+ templateTitle,
;
/**
* Convert String to TextFieldName
diff --git a/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java b/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java index c38fe3297..72e92c24b 100644 --- a/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java +++ b/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java @@ -32,5 +32,5 @@ package com.smartdevicelink; // THIS FILE IS AUTO GENERATED, DO NOT MODIFY!! public final class BuildConfig { - public static final String VERSION_NAME = "4.9.0"; + public static final String VERSION_NAME = "4.9.1"; }
\ No newline at end of file |