diff options
author | Bilal Alsharifi <599206+bilal-alsharifi@users.noreply.github.com> | 2019-08-01 15:54:59 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-01 15:54:59 -0400 |
commit | 5ea3f89124f070f8bf9a97eeb70854ee140f23f5 (patch) | |
tree | 4030f0d8b8e592aa26e43d4133a37b1d7f31e331 | |
parent | 4e429a8c8446a95930c1177b800eb53cc0a636f7 (diff) | |
parent | 43a025760a7720cb98602a9e903f1ac2087f7574 (diff) | |
download | sdl_android-5ea3f89124f070f8bf9a97eeb70854ee140f23f5.tar.gz |
Merge pull request #1113 from smartdevicelink/feature/sdl_0116_open_menu_rpc
Implement SDL-0116 Open Menu RPC
13 files changed, 623 insertions, 61 deletions
diff --git a/.travis.yml b/.travis.yml index 51e3dfe7a..625caaa52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ android: - tools - platform-tools - ndk-bundle - + # The BuildTools version used by your project - build-tools-28.0.3 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/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/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/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 fc204df49..bafd9093f 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 @@ -103,6 +103,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; @@ -609,7 +610,8 @@ public class ProxyBridge implements IProxyListener{ public void onGetCloudAppProperties(GetCloudAppPropertiesResponse response) { onRPCReceived(response); } -@Override + + @Override public void onPublishAppServiceResponse(PublishAppServiceResponse response){ onRPCReceived(response); } @@ -645,6 +647,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/proxy/SdlProxyBase.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java index b7d81716b..52439d821 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 @@ -3702,12 +3702,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> _mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onCloseApplicationResponse( msg);
+ _proxyListener.onCloseApplicationResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onCloseApplicationResponse( msg);
+ _proxyListener.onCloseApplicationResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.UNPUBLISH_APP_SERVICE.toString())) {
@@ -3726,6 +3726,22 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> _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 +
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 dff87b5b0..90cc5294d 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java @@ -410,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 @@ -436,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(){ @@ -444,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/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 a7678f29e..88fcfcf2c 100644 --- a/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java +++ b/base/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java @@ -102,6 +102,7 @@ public enum FunctionID{ PERFORM_APP_SERVICES_INTERACTION(55, "PerformAppServiceInteraction"),
UNPUBLISH_APP_SERVICE(56, "UnpublishAppService"),
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 9f34940b6..1fd883185 100644 --- a/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java +++ b/base/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java @@ -95,6 +95,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;
@@ -424,11 +425,19 @@ public interface IProxyListenerBase { */
public void onCloseApplicationResponse(CloseApplicationResponse 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/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 |