summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Grover <joeygrover@gmail.com>2022-10-26 11:15:00 -0400
committerGitHub <noreply@github.com>2022-10-26 11:15:00 -0400
commitc5b805411cc285c0ade2933a22c4134c922a1b13 (patch)
tree2d6bcc3ff55fccd04604e79a53f110d4c09653b6
parentc1afd4f7d4af7cd6783d2c019b877153f84a6745 (diff)
parentb18ae828d4077cf6f039fc0d4d7081122c029e8f (diff)
downloadsdl_android-c5b805411cc285c0ade2933a22c4134c922a1b13.tar.gz
Merge pull request #1837 from smartdevicelink/release/5.6.0_RC5.6.0
Release/5.6.0
-rw-r--r--CHANGELOG.md22
-rw-r--r--VERSION2
-rwxr-xr-xandroid/hello_sdl_android/build.gradle13
-rwxr-xr-xandroid/hello_sdl_android/src/main/AndroidManifest.xml2
-rwxr-xr-xandroid/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/MainActivity.java74
-rwxr-xr-xandroid/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlService.java6
-rw-r--r--android/sdl_android/build.gradle6
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/SystemCapabilityManagerTests.java3
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/PresentAlertOperationTest.java40
-rw-r--r--android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java208
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java2
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java13
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/session/SdlSession.java20
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java32
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java14
-rw-r--r--android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java4
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseSystemCapabilityManager.java15
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java77
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/PresentAlertOperation.java21
-rw-r--r--base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java62
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/AddCommand.java6
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/AddSubMenu.java2
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/BodyInformation.java7
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/MenuParams.java14
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/OnVehicleData.java18
-rw-r--r--base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java8
-rw-r--r--javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java2
-rw-r--r--javaSE/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java2
28 files changed, 541 insertions, 154 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60aacacc2..f5b1a9cb0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,15 +1,29 @@
-# 5.5.0 Release Notes
+# 5.6.0 Release Notes
## Summary:
||Version|
|--|--|
| **Protocol** | 5.4.1
| **RPC** | 8.0.0
-| **Tested Targeting** | Android 31
+| **Tested Targeting** | Android 33
## Bug Fixes:
-- [ScreenManager tries to upload images even if they are not supported (SDL 2.0)](https://github.com/smartdevicelink/sdl_java_suite/issues/1738)
+- [Images not displaying correctly on Alerts sent via AlertManager](https://github.com/smartdevicelink/sdl_java_suite/issues/1835)
-- [Fix formatting of many tables within the documentation](https://github.com/smartdevicelink/sdl_java_suite/pull/1810)
+- [TemplateConfiguration not set in currentScreenData in TextAndGraphicManager on RPC >= 6 ](https://github.com/smartdevicelink/sdl_java_suite/issues/1833)
+
+- [Setting bad data in one T&G field then good data quickly in another can lead to the good data failing.](https://github.com/smartdevicelink/sdl_java_suite/issues/1828)
+
+- [ForegroundServiceStartNotAllowedException in SdlRouterStatusProvider](https://github.com/smartdevicelink/sdl_java_suite/issues/1829)
+
+- [`DisplayCapabilities` `ScreenParams` null in SystemCapabilityManager](https://github.com/smartdevicelink/sdl_java_suite/issues/1824)
+
+- [Media app does not disappear from Sync after bluetooth connection is turned off when USB is plugged in if the app RequiresAudioSupport flag is set to true](https://github.com/smartdevicelink/sdl_java_suite/issues/1802)
+
+- [Android 13 issues](https://github.com/smartdevicelink/sdl_java_suite/issues/1812)
+
+- [ForegroundServiceStartNotAllowedException in SdlRouterService ](https://github.com/smartdevicelink/sdl_java_suite/issues/1815)
+
+- [SdlArtwork clone issue](https://github.com/smartdevicelink/sdl_java_suite/issues/1818)
diff --git a/VERSION b/VERSION
index d50359de1..1bc788d3b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.5.0
+5.6.0
diff --git a/android/hello_sdl_android/build.gradle b/android/hello_sdl_android/build.gradle
index 5feeba93f..fa8a08a93 100755
--- a/android/hello_sdl_android/build.gradle
+++ b/android/hello_sdl_android/build.gradle
@@ -1,13 +1,15 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 31
+ compileSdkVersion 33
defaultConfig {
applicationId "com.sdl.hellosdlandroid"
minSdkVersion 16
- targetSdkVersion 31
+ targetSdkVersion 33
versionCode 1
versionName "1.0"
+ buildConfigField 'String', 'APP_TYPE', '"DEFAULT"'
+ buildConfigField 'String', 'REQUIRE_AUDIO_OUTPUT', '"FALSE"'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
@@ -42,6 +44,13 @@ android {
buildConfigField 'String', 'TRANSPORT', '"TCP"'
buildConfigField 'String', 'SECURITY', '"OFF"'
}
+ requiresAudioOutput {
+ buildConfigField 'String', 'TRANSPORT', '"MULTI"'
+ buildConfigField 'String', 'SECURITY', '"OFF"'
+ buildConfigField 'String', 'APP_TYPE', '"MEDIA"'
+ buildConfigField 'String', 'REQUIRE_AUDIO_OUTPUT', '"TRUE"'
+
+ }
}
lintOptions {
disable 'GoogleAppIndexingWarning'
diff --git a/android/hello_sdl_android/src/main/AndroidManifest.xml b/android/hello_sdl_android/src/main/AndroidManifest.xml
index 415aa66c2..6b577c5a2 100755
--- a/android/hello_sdl_android/src/main/AndroidManifest.xml
+++ b/android/hello_sdl_android/src/main/AndroidManifest.xml
@@ -6,6 +6,8 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
tools:targetApi="31"/>
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS"
+ tools:targetApi="33"/>
<uses-permission android:name="android.permission.INTERNET" />
<!-- Required to check if WiFi is enabled -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/MainActivity.java b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/MainActivity.java
index 8497e3b73..44999945f 100755
--- a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/MainActivity.java
+++ b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/MainActivity.java
@@ -1,18 +1,17 @@
package com.sdl.hellosdlandroid;
+import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
-
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
-
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@@ -23,12 +22,18 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
-
if (BuildConfig.TRANSPORT.equals("MULTI") || BuildConfig.TRANSPORT.equals("MULTI_HB")) {
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !checkPermission()) {
- requestPermission();
- return;
+ String[] permissionsNeeded = permissionsNeeded();
+ if (permissionsNeeded.length > 0) {
+ requestPermission(permissionsNeeded, REQUEST_CODE);
+ for (String permission : permissionsNeeded) {
+ if (Manifest.permission.BLUETOOTH_CONNECT.equals(permission)) {
+ // We need to request BLUETOOTH_CONNECT permission to connect to SDL via Bluetooth
+ return;
+ }
+ }
}
+
//If we are connected to a module we want to start our SdlService
SdlReceiver.queryForConnectedService(this);
} else if (BuildConfig.TRANSPORT.equals("TCP")){
@@ -37,12 +42,39 @@ public class MainActivity extends AppCompatActivity {
}
}
- private boolean checkPermission() {
- return PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(getApplicationContext(), BLUETOOTH_CONNECT);
+ /**
+ * Boolean method that checks API level and check to see if we need to request BLUETOOTH_CONNECT permission
+ * @return false if we need to request BLUETOOTH_CONNECT permission
+ */
+ private boolean hasBTPermission() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? checkPermission(Manifest.permission.BLUETOOTH_CONNECT) : true;
+ }
+
+ /**
+ * Boolean method that checks API level and check to see if we need to request POST_NOTIFICATIONS permission
+ * @return false if we need to request POST_NOTIFICATIONS permission
+ */
+ private boolean hasPNPermission() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ? checkPermission(Manifest.permission.POST_NOTIFICATIONS) : true;
}
- private void requestPermission() {
- ActivityCompat.requestPermissions(this, new String[]{BLUETOOTH_CONNECT}, REQUEST_CODE);
+ private boolean checkPermission(String permission) {
+ return PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(getApplicationContext(), permission);
+ }
+
+ private void requestPermission(String[] permissions, int REQUEST_CODE) {
+ ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE);
+ }
+
+ private @NonNull String[] permissionsNeeded() {
+ ArrayList<String> result = new ArrayList<>();
+ if (!hasBTPermission()) {
+ result.add(Manifest.permission.BLUETOOTH_CONNECT);
+ }
+ if (!hasPNPermission()) {
+ result.add(Manifest.permission.POST_NOTIFICATIONS);
+ }
+ return (result.toArray(new String[result.size()]));
}
@Override
@@ -50,11 +82,21 @@ public class MainActivity extends AppCompatActivity {
switch (requestCode) {
case REQUEST_CODE:
if (grantResults.length > 0) {
-
- boolean btConnectGranted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
-
- if (btConnectGranted) {
- SdlReceiver.queryForConnectedService(this);
+ for (int i = 0; i < grantResults.length; i++) {
+ if (permissions[i].equals(Manifest.permission.BLUETOOTH_CONNECT)) {
+ boolean btConnectGranted =
+ grantResults[i] == PackageManager.PERMISSION_GRANTED;
+ if (btConnectGranted) {
+ SdlReceiver.queryForConnectedService(this);
+ }
+ } else if (permissions[i].equals(Manifest.permission.POST_NOTIFICATIONS)) {
+ boolean postNotificationGranted =
+ grantResults[i] == PackageManager.PERMISSION_GRANTED;
+ if (!postNotificationGranted) {
+ // User denied permission, Notifications for SDL will not appear
+ // on Android 13 devices.
+ }
+ }
}
}
break;
diff --git a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlService.java b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlService.java
index 59daf2050..be147af0b 100755
--- a/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlService.java
+++ b/android/hello_sdl_android/src/main/java/com/sdl/hellosdlandroid/SdlService.java
@@ -162,6 +162,9 @@ public class SdlService extends Service {
securityLevel = MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF;
}
transport = new MultiplexTransportConfig(this, APP_ID, securityLevel);
+ if (BuildConfig.REQUIRE_AUDIO_OUTPUT.equals("TRUE") ) {
+ ((MultiplexTransportConfig)transport).setRequiresAudioSupport(true);
+ }
} else if (BuildConfig.TRANSPORT.equals("TCP")) {
transport = new TCPTransportConfig(TCP_PORT, DEV_MACHINE_IP_ADDRESS, true);
} else if (BuildConfig.TRANSPORT.equals("MULTI_HB")) {
@@ -172,7 +175,8 @@ public class SdlService extends Service {
// The app type to be used
Vector<AppHMIType> appType = new Vector<>();
- appType.add(AppHMIType.DEFAULT);
+ appType.add(AppHMIType.valueForString(BuildConfig.APP_TYPE));
+
// The manager listener helps you know when certain events that pertain to the SDL Manager happen
// Here we will listen for ON_HMI_STATUS and ON_COMMAND notifications
diff --git a/android/sdl_android/build.gradle b/android/sdl_android/build.gradle
index b0072a6fd..c7cce6954 100644
--- a/android/sdl_android/build.gradle
+++ b/android/sdl_android/build.gradle
@@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 31
+ compileSdkVersion 33
defaultConfig {
minSdkVersion 16
- targetSdkVersion 31
- versionCode 23
+ targetSdkVersion 33
+ versionCode 24
versionName new File(projectDir.path, ('/../../VERSION')).text.trim()
buildConfigField "String", "VERSION_NAME", '\"' + versionName + '\"'
resValue "string", "SDL_LIB_VERSION", '\"' + versionName + '\"'
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/SystemCapabilityManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/SystemCapabilityManagerTests.java
index 03854d3ee..abe187cc8 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/SystemCapabilityManagerTests.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/lifecycle/SystemCapabilityManagerTests.java
@@ -176,8 +176,9 @@ public class SystemCapabilityManagerTests {
convertedCapabilities.setImageFields(defaultMainWindow.getImageFields());
convertedCapabilities.setTemplatesAvailable(defaultMainWindow.getTemplatesAvailable());
convertedCapabilities.setNumCustomPresetsAvailable(defaultMainWindow.getNumCustomPresetsAvailable());
- convertedCapabilities.setMediaClockFormats(new ArrayList<MediaClockFormat>()); // mandatory field but can be empty
+ convertedCapabilities.setMediaClockFormats(TestValues.GENERAL_MEDIACLOCKFORMAT_LIST); // mandatory field but can be empty
convertedCapabilities.setGraphicSupported(defaultMainWindow.getImageTypeSupported().contains(ImageType.DYNAMIC));
+ convertedCapabilities.setScreenParams(TestValues.GENERAL_SCREENPARAMS);
return convertedCapabilities;
}
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/PresentAlertOperationTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/PresentAlertOperationTest.java
index 5f69010f1..4e105e1f8 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/PresentAlertOperationTest.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/PresentAlertOperationTest.java
@@ -27,6 +27,7 @@ import com.smartdevicelink.proxy.rpc.WindowCapability;
import com.smartdevicelink.proxy.rpc.enums.FileType;
import com.smartdevicelink.proxy.rpc.enums.ImageFieldName;
import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities;
+import com.smartdevicelink.proxy.rpc.enums.StaticIconName;
import com.smartdevicelink.proxy.rpc.enums.TextFieldName;
import com.smartdevicelink.test.TestValues;
@@ -42,7 +43,6 @@ import java.util.List;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -167,7 +167,7 @@ public class PresentAlertOperationTest {
builder.setShowWaitIndicator(true);
alertView = builder.build();
- defaultMainWindowCapability = getWindowCapability(3);
+ defaultMainWindowCapability = getWindowCapability(3, true);
speechCapabilities = new ArrayList<SpeechCapabilities>();
speechCapabilities.add(SpeechCapabilities.FILE);
alertCompletionListener = new AlertCompletionListener() {
@@ -186,13 +186,13 @@ public class PresentAlertOperationTest {
// Same response works for uploading artworks as it does for files
when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
- WindowCapability windowCapability = getWindowCapability(1);
+ WindowCapability windowCapability = getWindowCapability(1, true);
PresentAlertOperation presentAlertOperation = new PresentAlertOperation(internalInterface, alertView, windowCapability, speechCapabilities, fileManager, 1, alertCompletionListener, alertSoftButtonClearListener);
Alert alert = presentAlertOperation.alertRpc();
assertEquals(alert.getAlertText1(), alertView.getText() + " - " + alertView.getSecondaryText() + " - " + alertView.getTertiaryText());
- windowCapability = getWindowCapability(2);
+ windowCapability = getWindowCapability(2, true);
presentAlertOperation = new PresentAlertOperation(internalInterface, alertView, windowCapability, speechCapabilities, fileManager, 1, alertCompletionListener, alertSoftButtonClearListener);
alert = presentAlertOperation.alertRpc();
@@ -258,7 +258,23 @@ public class PresentAlertOperationTest {
verify(fileManager, times(1)).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class));
verify(internalInterface, times(1)).sendRPC(any(Alert.class));
}
+ @Test
+ public void testPresentStaticIcon() {
+ doAnswer(onAlertSuccess).when(internalInterface).sendRPC(any(Alert.class));
+ // Same response works for uploading artworks as it does for files
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(6, 0));
+ when(fileManager.fileNeedsUpload(any(SdlFile.class))).thenReturn(false);
+
+ alertView.setIcon(new SdlArtwork(StaticIconName.LEFT));
+ PresentAlertOperation presentAlertOperationStaticIcon = new PresentAlertOperation(internalInterface, alertView, defaultMainWindowCapability, speechCapabilities, fileManager, 1, alertCompletionListener, alertSoftButtonClearListener);
+
+ // Test Images need to be uploaded, sending text and uploading images
+ presentAlertOperationStaticIcon.onExecute();
+ // Verifies that uploadArtworks gets called only with the fist presentAlertOperation.onExecute call
+ verify(fileManager, times(0)).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class));
+ verify(internalInterface, times(1)).sendRPC(any(Alert.class));
+ }
@Test
public void testCancelOperation() {
//Cancel right away
@@ -267,7 +283,7 @@ public class PresentAlertOperationTest {
verify(internalInterface, times(0)).sendRPC(any(Alert.class));
}
- private WindowCapability getWindowCapability(int numberOfAlertFields) {
+ private WindowCapability getWindowCapability(int numberOfAlertFields, boolean supportsAlertIcon) {
TextField alertText1 = new TextField();
alertText1.setName(TextFieldName.alertText1);
TextField alertText2 = new TextField();
@@ -294,13 +310,13 @@ public class PresentAlertOperationTest {
WindowCapability windowCapability = new WindowCapability();
windowCapability.setTextFields(returnList);
- ImageField imageField = new ImageField();
- imageField.setName(ImageFieldName.alertIcon);
- List<ImageField> imageFieldList = new ArrayList<>();
- imageFieldList.add(imageField);
- windowCapability.setImageFields(imageFieldList);
-
- windowCapability.setImageFields(imageFieldList);
+ if (supportsAlertIcon) {
+ ImageField imageField = new ImageField();
+ imageField.setName(ImageFieldName.alertIcon);
+ List<ImageField> imageFieldList = new ArrayList<>();
+ imageFieldList.add(imageField);
+ windowCapability.setImageFields(imageFieldList);
+ }
SoftButtonCapabilities softButtonCapabilities = new SoftButtonCapabilities();
softButtonCapabilities.setImageSupported(TestValues.GENERAL_BOOLEAN);
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java
index 4af040863..d2a821e23 100644
--- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java
+++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java
@@ -52,20 +52,24 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import junit.framework.TestCase;
+
@RunWith(AndroidJUnit4.class)
public class TextAndGraphicUpdateOperationTest {
private TextAndGraphicUpdateOperation textAndGraphicUpdateOperation;
private String textField1, textField2, textField3, textField4, mediaTrackField, title;
- private MetadataType textField1Type, textField2Type, textField3Type, textField4Type;
- private SdlArtwork testArtwork1, testArtwork2, testArtwork3, testArtwork4;
- private TextAlignment textAlignment;
+ private String textField1Fail, textField2Fail, textField3Fail, textField4Fail, mediaTrackFieldFail, titleFail;
+ private MetadataType textField1Type, textField2Type, textField3Type, textField4Type, textFieldFailType;
+ private SdlArtwork testArtwork1, testArtwork2, testArtwork3, testArtwork4, testArtworkFail;
+ private TextAlignment textAlignment, textAlignmentFail;
private WindowCapability defaultMainWindowCapability;
private TextAndGraphicState currentScreenData;
+ private TextAndGraphicState errorTestState, errorTestState2;
private CompletionListener listener;
private TextAndGraphicManager.CurrentScreenDataUpdatedListener currentScreenDataUpdatedListener;
private SdlArtwork blankArtwork;
- private TemplateConfiguration configuration;
+ private TemplateConfiguration configuration, configurationFail, configurationOld;
ISdl internalInterface;
FileManager fileManager;
@@ -188,6 +192,13 @@ public class TextAndGraphicUpdateOperationTest {
mediaTrackField = "dudes";
title = "dudes";
+ textField1Fail = "It is\nbad data";
+ textField2Fail = "Wednesday\nbad data";
+ textField3Fail = "My\nbad data";
+ textField4Fail = "Dudes\nbad data";
+ mediaTrackFieldFail = "dudes\nbad data";
+ titleFail = "dudes\nbad data";
+
blankArtwork = new SdlArtwork();
blankArtwork.setType(FileType.GRAPHIC_PNG);
blankArtwork.setName("blankArtwork");
@@ -197,9 +208,10 @@ public class TextAndGraphicUpdateOperationTest {
textField2Type = MetadataType.MEDIA_TITLE;
textField3Type = MetadataType.MEDIA_TITLE;
textField4Type = MetadataType.MEDIA_TITLE;
-
+ textFieldFailType = MetadataType.valueForString("failType");
textAlignment = TextAlignment.CENTERED;
+ textAlignmentFail = TextAlignment.valueForString("failAlignment");
testArtwork1 = new SdlArtwork();
testArtwork1.setName("testFile1");
@@ -225,9 +237,39 @@ public class TextAndGraphicUpdateOperationTest {
testArtwork4.setUri(uri4);
testArtwork4.setType(FileType.GRAPHIC_PNG);
+ testArtworkFail = new SdlArtwork();
+ testArtworkFail.setName("testFileFail");
+ Uri uriFail = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/no_file");
+ testArtworkFail.setUri(uriFail);
+ testArtworkFail.setType(FileType.GRAPHIC_PNG);
+
configuration = new TemplateConfiguration();
configuration.setTemplate(PredefinedLayout.GRAPHIC_WITH_TEXT.toString());
+ configurationOld = new TemplateConfiguration();
+ configurationOld.setTemplate(PredefinedLayout.TEXT_WITH_GRAPHIC.toString());
+ configurationFail = new TemplateConfiguration();
+ configurationFail.setTemplate("failConfiguration");
+
+ errorTestState = new TextAndGraphicState();
+ errorTestState2 = new TextAndGraphicState();
+
+ errorTestState2.setTextField1(textField1);
+ errorTestState2.setTextField2(textField2);
+ errorTestState2.setTextField3(textField3Fail);
+ errorTestState2.setTextField4(textField4Fail);
+ errorTestState2.setTextField1Type(textFieldFailType);
+ errorTestState2.setTextField2Type(textFieldFailType);
+ errorTestState2.setTextField3Type(textFieldFailType);
+ errorTestState2.setTextField4Type(textFieldFailType);
+ errorTestState2.setMediaTrackTextField(mediaTrackFieldFail);
+ errorTestState2.setTitle(titleFail);
+ errorTestState2.setPrimaryGraphic(testArtworkFail);
+ errorTestState2.setSecondaryGraphic(testArtworkFail);
+ errorTestState2.setTextAlignment(textAlignmentFail);
+ errorTestState2.setTemplateConfiguration(configurationFail);
+
+
currentScreenData = new TextAndGraphicState();
currentScreenData.setTextField1("Old");
currentScreenData.setTextField2("Text");
@@ -236,17 +278,15 @@ public class TextAndGraphicUpdateOperationTest {
currentScreenData.setPrimaryGraphic(testArtwork1);
currentScreenData.setSecondaryGraphic(testArtwork2);
- currentScreenData.setTemplateConfiguration(configuration);
+ currentScreenData.setTemplateConfiguration(configurationOld);
currentScreenDataUpdatedListener = new TextAndGraphicManager.CurrentScreenDataUpdatedListener() {
@Override
public void onUpdate(TextAndGraphicState newState) {
-
}
@Override
- public void onError() {
-
+ public void onError(TextAndGraphicState errorState) {
}
};
@@ -257,7 +297,6 @@ public class TextAndGraphicUpdateOperationTest {
textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener);
}
-
private void setUpCompletionListener() {
listener = new CompletionListener() {
@Override
@@ -1010,11 +1049,158 @@ public class TextAndGraphicUpdateOperationTest {
mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type, configuration);
textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener);
textAndGraphicUpdateOperation.onExecute();
- assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getTemplateConfiguration().getStore(), configuration.getStore());
// Verifies that uploadArtworks does not get called because a sendShow failed with text and layout change
verify(fileManager, times(0)).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class));
}
+ @Test
+ public void testOnShowFailBadDataDoesNotUpdateScreen(){
+ doAnswer(onShowFail).when(internalInterface).sendRPC(any(Show.class));
+ doAnswer(onArtworkUploadSuccess).when(fileManager).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class));
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(4, 0));
+
+ TextAndGraphicState textsAndGraphicsState = new TextAndGraphicState(textField1Fail, textField2Fail, textField3Fail, textField4Fail,
+ mediaTrackFieldFail, titleFail, testArtworkFail, testArtworkFail, textAlignmentFail, textFieldFailType, textFieldFailType, textFieldFailType, textFieldFailType, configurationFail);
+ textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener);
+
+ // Test Images need to be uploaded, sending text and uploading images
+ textAndGraphicUpdateOperation.onExecute();
+
+ // Sending in bad data should result in no updates to the current screen
+ assertEquals("Old", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1());
+ assertEquals("Text", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2());
+ assertEquals("Not", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3());
+ assertEquals("Important", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getMediaTrackTextField());
+ assertEquals(testArtwork1, textAndGraphicUpdateOperation.getCurrentScreenData().getPrimaryGraphic());
+ assertEquals(testArtwork2, textAndGraphicUpdateOperation.getCurrentScreenData().getSecondaryGraphic());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextAlignment());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4Type());
+ assertEquals(configurationOld, textAndGraphicUpdateOperation.getCurrentScreenData().getTemplateConfiguration());
+ }
+
+ @Test
+ public void testUpdateTargetStateWithErrorStateNullDoesNotUpdateCurrentScreen() {
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(4, 0));
+
+ errorTestState.setTextField1(null);
+ errorTestState.setTextField2(null);
+ errorTestState.setTextField3(null);
+ errorTestState.setTextField4(null);
+ errorTestState.setTextField1Type(null);
+ errorTestState.setTextField2Type(null);
+ errorTestState.setTextField3Type(null);
+ errorTestState.setTextField4Type(null);
+ errorTestState.setMediaTrackTextField(null);
+ errorTestState.setTitle(null);
+ errorTestState.setPrimaryGraphic(null);
+ errorTestState.setSecondaryGraphic(null);
+ errorTestState.setTextAlignment(null);
+ errorTestState.setTemplateConfiguration(null);
+
+ textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, errorTestState, listener, currentScreenDataUpdatedListener);
+ // Testing updateTargetStateWithErrorState method
+ textAndGraphicUpdateOperation.updateTargetStateWithErrorState(errorTestState);
+ textAndGraphicUpdateOperation.onExecute();
+
+ // Setting fields to null should result in no updates to the current screen
+ assertEquals("Old", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1());
+ assertEquals("Text", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2());
+ assertEquals("Not", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3());
+ assertEquals("Important", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getMediaTrackTextField());
+ assertEquals(testArtwork1, textAndGraphicUpdateOperation.getCurrentScreenData().getPrimaryGraphic());
+ assertEquals(testArtwork2, textAndGraphicUpdateOperation.getCurrentScreenData().getSecondaryGraphic());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextAlignment());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4Type());
+ assertEquals(configurationOld, textAndGraphicUpdateOperation.getCurrentScreenData().getTemplateConfiguration());
+ }
+
+ @Test
+ public void testUpdateTargetStateWithErrorBadDataDoesNotUpdateCurrentScreen() {
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(4, 0));
+
+ errorTestState.setTextField1(textField1Fail);
+ errorTestState.setTextField2(textField2Fail);
+ errorTestState.setTextField3(textField3Fail);
+ errorTestState.setTextField4(textField4Fail);
+ errorTestState.setTextField1Type(textFieldFailType);
+ errorTestState.setTextField2Type(textFieldFailType);
+ errorTestState.setTextField3Type(textFieldFailType);
+ errorTestState.setTextField4Type(textFieldFailType);
+ errorTestState.setMediaTrackTextField(mediaTrackFieldFail);
+ errorTestState.setTitle(titleFail);
+ errorTestState.setPrimaryGraphic(testArtworkFail);
+ errorTestState.setSecondaryGraphic(testArtworkFail);
+ errorTestState.setTextAlignment(textAlignmentFail);
+ errorTestState.setTemplateConfiguration(configurationFail);
+
+ textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, errorTestState, listener, currentScreenDataUpdatedListener);
+ // Testing updateTargetStateWithErrorState method
+ textAndGraphicUpdateOperation.updateTargetStateWithErrorState(errorTestState);
+ textAndGraphicUpdateOperation.onExecute();
+
+ // Setting bad data should result in no updates to the current screen
+ assertEquals("Old", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1());
+ assertEquals("Text", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2());
+ assertEquals("Not", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3());
+ assertEquals("Important", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getMediaTrackTextField());
+ assertEquals(testArtwork1, textAndGraphicUpdateOperation.getCurrentScreenData().getPrimaryGraphic());
+ assertEquals(testArtwork2, textAndGraphicUpdateOperation.getCurrentScreenData().getSecondaryGraphic());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextAlignment());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4Type());
+ assertEquals(configurationOld, textAndGraphicUpdateOperation.getCurrentScreenData().getTemplateConfiguration());
+ }
+
+ @Test
+ public void testUpdateTargetStateWithErrorBadDataAndGoodData() {
+ when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(4, 0));
+
+ errorTestState2.setTextField1(textField1Fail);
+ errorTestState2.setTextField2(textField2);
+ errorTestState2.setTextField3(null);
+ errorTestState2.setTextField4(textField4Fail);
+ errorTestState2.setTextField1Type(textFieldFailType);
+ errorTestState2.setTextField2Type(textFieldFailType);
+ errorTestState2.setTextField3Type(textFieldFailType);
+ errorTestState2.setTextField4Type(textFieldFailType);
+ errorTestState2.setMediaTrackTextField(mediaTrackFieldFail);
+ errorTestState2.setTitle(titleFail);
+ errorTestState2.setPrimaryGraphic(testArtworkFail);
+ errorTestState2.setSecondaryGraphic(testArtworkFail);
+ errorTestState2.setTextAlignment(textAlignmentFail);
+ errorTestState2.setTemplateConfiguration(configurationFail);
+
+ textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, errorTestState2, listener, currentScreenDataUpdatedListener);
+ // Testing updateTargetStateWithErrorState method
+ textAndGraphicUpdateOperation.updateTargetStateWithErrorState(errorTestState2);
+ textAndGraphicUpdateOperation.onExecute();
+
+ // Setting mix of good and bad data should result in only updates to those fields with good data
+ assertEquals("Old", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1());
+ assertEquals(errorTestState2.getTextField2(), textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2());
+ assertEquals("Not", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3());
+ assertEquals("Important", textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getMediaTrackTextField());
+ assertEquals(errorTestState2.getPrimaryGraphic(), textAndGraphicUpdateOperation.getCurrentScreenData().getPrimaryGraphic());
+ assertEquals(errorTestState2.getSecondaryGraphic(), textAndGraphicUpdateOperation.getCurrentScreenData().getSecondaryGraphic());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextAlignment());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField1Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField2Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField3Type());
+ TestCase.assertNull(textAndGraphicUpdateOperation.getCurrentScreenData().getTextField4Type());
+ assertEquals(configurationOld, textAndGraphicUpdateOperation.getCurrentScreenData().getTemplateConfiguration());
+ }
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
index b46745917..bc7dfe3bb 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
@@ -160,7 +160,7 @@ public class SdlArtwork extends SdlFile implements Cloneable {
public SdlArtwork clone() {
SdlArtwork artwork = (SdlArtwork) super.clone();
if (artwork != null) {
- artwork.imageRPC = artwork.createImageRPC();
+ artwork.imageRPC = null;
return artwork;
}
return null;
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java
index bfe73c19f..ae8ba7b23 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java
@@ -55,6 +55,7 @@ import com.smartdevicelink.transport.enums.TransportType;
import com.smartdevicelink.transport.utl.TransportRecord;
import com.smartdevicelink.util.AndroidTools;
import com.smartdevicelink.util.DebugTool;
+import com.smartdevicelink.util.MediaStreamingStatus;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -80,7 +81,17 @@ public class LifecycleManager extends BaseLifecycleManager {
synchronized (SESSION_LOCK) {
if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.MULTIPLEX)) {
- this.session = new SdlSession(sdlSessionListener, (MultiplexTransportConfig) _transportConfig);
+ MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig) _transportConfig;
+ this.session = new SdlSession(sdlSessionListener, multiplexTransportConfig);
+ if (multiplexTransportConfig.requiresAudioSupport()) {
+ this.session.setMediaStreamingStatusCallback(new MediaStreamingStatus.Callback() {
+ @Override
+ public void onAudioNoLongerAvailable() {
+ clean(true);
+ onClose("Audio output no longer available", null, SdlDisconnectedReason.DEFAULT);
+ }
+ });
+ }
} else if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.TCP)) {
this.session = new SdlSession(sdlSessionListener, (TCPTransportConfig) _transportConfig);
} else {
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/session/SdlSession.java b/android/sdl_android/src/main/java/com/smartdevicelink/session/SdlSession.java
index 74701c867..633904bb0 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/session/SdlSession.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/session/SdlSession.java
@@ -62,6 +62,7 @@ public class SdlSession extends BaseSdlSession {
WeakReference<Context> contextWeakReference;
MediaStreamingStatus mediaStreamingStatus;
boolean requiresAudioSupport = false;
+ MediaStreamingStatus.Callback mediaStreamingStatusCallback;
public SdlSession(ISdlSessionListener listener, MultiplexTransportConfig config) {
super(listener, config);
@@ -79,6 +80,17 @@ public class SdlSession extends BaseSdlSession {
this.sessionListener = listener;
}
+ /**
+ * Sets a callback that is triggered when there are no audio output methods available. If this
+ * is set then the caller of this method will be responsible for shutting the session down.
+ *
+ * @param mediaStreamingStatusCallback the callback that will be triggered when audio output is
+ * no longer available.
+ */
+ public void setMediaStreamingStatusCallback(MediaStreamingStatus.Callback mediaStreamingStatusCallback) {
+ this.mediaStreamingStatusCallback = mediaStreamingStatusCallback;
+ }
+
protected SdlProtocolBase getSdlProtocolImplementation() {
if (transportConfig instanceof MultiplexTransportConfig) {
return new SdlProtocol(this, (MultiplexTransportConfig) transportConfig);
@@ -94,8 +106,12 @@ public class SdlSession extends BaseSdlSession {
mediaStreamingStatus = new MediaStreamingStatus(contextWeakReference.get(), new MediaStreamingStatus.Callback() {
@Override
public void onAudioNoLongerAvailable() {
- close();
- shutdown("Audio output no longer available");
+ if (mediaStreamingStatusCallback != null) {
+ mediaStreamingStatusCallback.onAudioNoLongerAvailable();
+ } else {
+ close();
+ shutdown("Audio output no longer available");
+ }
}
});
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
index 7bed1b482..936989f5c 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
@@ -34,6 +34,8 @@ package com.smartdevicelink.transport;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
+import android.app.ForegroundServiceStartNotAllowedException;
+import android.app.ServiceStartNotAllowedException;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
@@ -282,8 +284,8 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver {
restart.putExtra(LOCAL_ROUTER_SERVICE_DID_START_OWN, true);
context.sendBroadcast(restart);
- } catch (SecurityException e) {
- DebugTool.logError(TAG, "Security exception, process is bad");
+ } catch (SecurityException | IllegalStateException e) {
+ handleStartServiceException(e);
}
}
@@ -478,9 +480,8 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver {
} else {
context.startService(intent);
}
- } catch (SecurityException e) {
- DebugTool.logError(TAG, "Security exception, process is bad");
- // This service could not be started
+ } catch (SecurityException | IllegalStateException e) {
+ handleStartServiceException(e);
}
}
@@ -599,6 +600,27 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver {
return false;
}
+ /**
+ * Convenience method to log details on the specific exception that occurred while attempting to
+ * start a foreground service.
+ * @param e the exception that occurred
+ */
+ protected static void handleStartServiceException(Exception e) {
+ if (e instanceof SecurityException) {
+ DebugTool.logError(TAG, "Security exception, process is bad");
+ return;
+ } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ if (e instanceof ForegroundServiceStartNotAllowedException) {
+ DebugTool.logError(TAG, "Not allowed to start service in foreground");
+ return;
+ } else if (e instanceof ServiceStartNotAllowedException) {
+ DebugTool.logError(TAG, "Not allowed to start service in current state");
+ return;
+ }
+ }
+ DebugTool.logError(TAG, "Unable to start service for unknown reason");
+ }
+
private static SdlDeviceListener getSdlDeviceListener(Context context, BluetoothDevice bluetoothDevice) {
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
index b90a55684..078fe104c 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java
@@ -136,11 +136,21 @@ public class SdlRouterStatusProvider {
} else {
bindingIntent.putExtra(FOREGROUND_EXTRA, true);
SdlBroadcastReceiver.setForegroundExceptionHandler(); //Prevent ANR in case the OS takes too long to start the service
- context.startForegroundService(bindingIntent);
+ try {
+ context.startForegroundService(bindingIntent);
+ } catch (SecurityException | IllegalStateException e) {
+ SdlBroadcastReceiver.handleStartServiceException(e);
+ }
}
bindingIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_STATUS);
- return context.bindService(bindingIntent, routerConnection, Context.BIND_AUTO_CREATE);
+ boolean didBind = false;
+ try {
+ didBind = context.bindService(bindingIntent, routerConnection, Context.BIND_AUTO_CREATE);
+ } catch (SecurityException | IllegalStateException e) {
+ SdlBroadcastReceiver.handleStartServiceException(e);
+ }
+ return didBind;
}
private void unBindFromService() {
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java
index 22ee5d1db..7bb2f753b 100644
--- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java
+++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java
@@ -202,8 +202,8 @@ public class USBAccessoryAttachmentActivity extends Activity {
}
- } catch (SecurityException e) {
- DebugTool.logError(TAG, "Security exception, process is bad");
+ } catch (SecurityException | IllegalStateException e) {
+ SdlBroadcastReceiver.handleStartServiceException(e);
}
} else {
if (usbAccessory != null) {
diff --git a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseSystemCapabilityManager.java b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseSystemCapabilityManager.java
index 1f6c663a8..927200876 100644
--- a/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseSystemCapabilityManager.java
+++ b/base/src/main/java/com/smartdevicelink/managers/lifecycle/BaseSystemCapabilityManager.java
@@ -172,6 +172,15 @@ abstract class BaseSystemCapabilityManager {
// if there are imageTypes in the response, we must assume graphics are supported
convertedCapabilities.setGraphicSupported(defaultMainWindow.getImageTypeSupported() != null && defaultMainWindow.getImageTypeSupported().size() > 0);
+ if (cachedSystemCapabilities.containsKey(SystemCapabilityType.DISPLAY)) {
+ // Copied from the RAI response, since this parameter is not present in WindowCapability
+ DisplayCapabilities displayCapabilitiesOld = (DisplayCapabilities) cachedSystemCapabilities.get(SystemCapabilityType.DISPLAY);
+ convertedCapabilities.setScreenParams(displayCapabilitiesOld.getScreenParams());
+ if (displayCapabilitiesOld.getMediaClockFormats() != null) {
+ convertedCapabilities.setMediaClockFormats(displayCapabilitiesOld.getMediaClockFormats());
+ }
+ }
+
return convertedCapabilities;
}
@@ -246,7 +255,11 @@ abstract class BaseSystemCapabilityManager {
for (WindowCapability windowCapability : display.getWindowCapabilities()) {
int currentWindowID = windowCapability.getWindowID() != null ? windowCapability.getWindowID() : PredefinedWindows.DEFAULT_WINDOW.getValue();
if (currentWindowID == windowID) {
- return windowCapability;
+ // Clone WindowCapability to prevent modification of stored WindowCapability in SystemCapabilityManager
+ WindowCapability windowCapabilityCopy = (WindowCapability) windowCapability.clone();
+ // A null windowID is assumed to be the DefaultWindow according to the spec, but that can be hard for developers to check, so set it explicitly.
+ windowCapabilityCopy.setWindowID(windowID);
+ return windowCapabilityCopy;
}
}
return null;
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 0a201fc22..92bc82817 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java
@@ -87,7 +87,6 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
private MetadataType textField1Type, textField2Type, textField3Type, textField4Type;
private TemplateConfiguration templateConfiguration;
TextAndGraphicUpdateOperation updateOperation;
- private CompletionListener currentOperationListener;
Queue transactionQueue;
//Constructors
@@ -175,36 +174,13 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
}
if (isDirty) {
isDirty = false;
- sdlUpdate(true, listener);
+ sdlUpdate(listener);
} else if (listener != null) {
listener.onComplete(true);
}
}
- private synchronized void sdlUpdate(Boolean supersedePreviousOperations, final CompletionListener listener) {
- if (this.transactionQueue.getTasksAsList().size() > 0 && supersedePreviousOperations) {
- // Transactions already in queue, we need to clear it out
- transactionQueue.clear();
- updateOperation = null;
- if (currentOperationListener != null) {
- currentOperationListener.onComplete(false);
- }
- }
-
- // Task can be READY, about to start and popped of the queue, so we have to cancel it, to prevent it from starting
- if (updateOperation != null && updateOperation.getState() == Task.READY && supersedePreviousOperations) {
- updateOperation.cancelTask();
- if (currentOperationListener != null) {
- currentOperationListener.onComplete(false);
- }
- }
-
- // If Task is IN_PROGRESS, it’s not on the queue, we need to mark it as cancelled. The task will return at some point when it checks its status and call the listener back
- if (updateOperation != null && updateOperation.getState() == Task.IN_PROGRESS && supersedePreviousOperations) {
- updateOperation.cancelTask();
- }
-
- currentOperationListener = listener;
+ private synchronized void sdlUpdate(final CompletionListener listener) {
CurrentScreenDataUpdatedListener currentScreenDataUpdateListener = new CurrentScreenDataUpdatedListener() {
@Override
@@ -217,13 +193,16 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
}
@Override
- public void onError() {
+ public void onError(TextAndGraphicState errorState) {
// Invalidate data that's different from our current screen data
resetFieldsToCurrentScreenData();
+ if (errorState != null) {
+ updatePendingOperationsWithFailedScreenState(errorState);
+ }
}
};
- updateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager.get(), defaultMainWindowCapability, currentScreenData, currentState(), currentOperationListener, currentScreenDataUpdateListener);
+ updateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager.get(), defaultMainWindowCapability, currentScreenData, currentState(), listener, currentScreenDataUpdateListener);
transactionQueue.add(updateOperation, false);
}
@@ -257,10 +236,20 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
}
}
+ void updatePendingOperationsWithFailedScreenState(TextAndGraphicState errorState) {
+ for (Task task : transactionQueue.getTasksAsList()) {
+ if (!(task instanceof TextAndGraphicUpdateOperation)) {
+ continue;
+ }
+ ((TextAndGraphicUpdateOperation) task).setCurrentScreenData(currentScreenData);
+ ((TextAndGraphicUpdateOperation) task).updateTargetStateWithErrorState(errorState);
+ }
+ }
+
interface CurrentScreenDataUpdatedListener {
void onUpdate(TextAndGraphicState newState);
- void onError();
+ void onError(TextAndGraphicState errorState);
}
@@ -317,7 +306,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
this.textAlignment = textAlignment;
// If we aren't batching, send the update immediately, if we are, set ourselves as dirty (so we know we should send an update after the batch ends)
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -330,7 +319,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setMediaTrackTextField(String mediaTrackTextField) {
this.mediaTrackTextField = mediaTrackTextField;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -343,7 +332,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField1(String textField1) {
this.textField1 = textField1;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -356,7 +345,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField2(String textField2) {
this.textField2 = textField2;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -369,7 +358,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField3(String textField3) {
this.textField3 = textField3;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -382,7 +371,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField4(String textField4) {
this.textField4 = textField4;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -395,7 +384,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField1Type(MetadataType textField1Type) {
this.textField1Type = textField1Type;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -408,7 +397,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField2Type(MetadataType textField2Type) {
this.textField2Type = textField2Type;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -421,7 +410,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField3Type(MetadataType textField3Type) {
this.textField3Type = textField3Type;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -434,7 +423,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTextField4Type(MetadataType textField4Type) {
this.textField4Type = textField4Type;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -447,7 +436,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setTitle(String title) {
this.title = title;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -460,7 +449,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setPrimaryGraphic(SdlArtwork primaryGraphic) {
this.primaryGraphic = primaryGraphic;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -473,7 +462,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void setSecondaryGraphic(SdlArtwork secondaryGraphic) {
this.secondaryGraphic = secondaryGraphic;
if (!batchingUpdates) {
- sdlUpdate(true, null);
+ sdlUpdate(null);
} else {
isDirty = true;
}
@@ -491,7 +480,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
void changeLayout(TemplateConfiguration templateConfiguration, CompletionListener listener) {
setTemplateConfiguration(templateConfiguration);
if (!batchingUpdates) {
- sdlUpdate(true, listener);
+ sdlUpdate(listener);
} else {
isDirty = true;
}
@@ -554,7 +543,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager {
updateTransactionQueueSuspended();
if (hasData()) {
// HAX: Capability updates cannot supersede earlier updates because of the case where a developer batched a `changeLayout` call w/ T&G changes on < 6.0 systems could cause this to come in before the operation completes. That would cause the operation to report a "failure" (because it was superseded by this call) when in fact the operation didn't fail at all and is just being adjusted.
- sdlUpdate(false, null);
+ sdlUpdate(null);
}
}
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/PresentAlertOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/PresentAlertOperation.java
index a85901d3c..31163627c 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/PresentAlertOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/PresentAlertOperation.java
@@ -77,6 +77,8 @@ public class PresentAlertOperation extends Task {
boolean isAlertPresented;
static int SOFTBUTTON_COUNT = 4;
private BaseAlertManager.AlertSoftButtonClearListener alertSoftButtonClearListener;
+ Boolean alertIconUploaded;
+ private List<SdlArtwork> artworksToBeUploaded;
public PresentAlertOperation(ISdl internalInterface, AlertView alertView, WindowCapability currentCapabilities, List<SpeechCapabilities> speechCapabilities, FileManager fileManager, Integer cancelId, AlertCompletionListener listener, BaseAlertManager.AlertSoftButtonClearListener alertSoftButtonClearListener) {
super("PresentAlertOperation");
@@ -89,6 +91,7 @@ public class PresentAlertOperation extends Task {
this.cancelId = cancelId;
this.isAlertPresented = false;
this.alertSoftButtonClearListener = alertSoftButtonClearListener;
+ alertIconUploaded = false;
this.alertView.canceledListener = new AlertCanceledListener() {
@Override
@@ -237,10 +240,15 @@ public class PresentAlertOperation extends Task {
* @param listener - CompletionListener called when all images have been uploaded.
*/
private void uploadImages(final CompletionListener listener) {
- List<SdlArtwork> artworksToBeUploaded = new ArrayList<>();
+ artworksToBeUploaded = new ArrayList<>();
- if (supportsAlertIcon() && fileManager.get() != null && fileManager.get().fileNeedsUpload(alertView.getIcon())) {
- artworksToBeUploaded.add(alertView.getIcon());
+ if (supportsAlertIcon() && alertView.getIcon() != null && fileManager.get() != null) {
+ if (fileManager.get().fileNeedsUpload(alertView.getIcon())) {
+ artworksToBeUploaded.add(alertView.getIcon());
+
+ } else if (fileManager.get().hasUploadedFile(alertView.getIcon()) || alertView.getIcon().isStaticIcon()) {
+ alertIconUploaded = true;
+ }
}
if (alertView.getSoftButtons() != null) {
@@ -275,6 +283,9 @@ public class PresentAlertOperation extends Task {
} else {
DebugTool.logInfo(TAG, "All alert images uploaded");
}
+ if (artworksToBeUploaded.contains(alertView.getIcon()) && (errors == null || !errors.containsKey(alertView.getIcon().getName()))) {
+ alertIconUploaded = true;
+ }
listener.onComplete(true);
}
});
@@ -362,9 +373,7 @@ public class PresentAlertOperation extends Task {
alert = assembleAlertText(alert);
alert.setDuration(alertView.getTimeout() * 1000);
- if (alertView.getIcon() != null && supportsAlertIcon() && !(fileManager.get().hasUploadedFile(alertView.getIcon()))) {
- alert.setAlertIcon(alertView.getIcon().getImageRPC());
- }
+ alert.setAlertIcon(alertIconUploaded ? alertView.getIcon().getImageRPC() : null);
alert.setProgressIndicator(alertView.isShowWaitIndicator());
alert.setCancelID(this.cancelId);
diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java
index 683820ee5..be6d6115f 100644
--- a/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java
+++ b/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java
@@ -1,5 +1,7 @@
package com.smartdevicelink.managers.screen;
+import androidx.annotation.NonNull;
+
import com.livio.taskmaster.Task;
import com.smartdevicelink.managers.CompletionListener;
import com.smartdevicelink.managers.ISdl;
@@ -24,6 +26,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+
/**
* Created by Julian Kast on 8/23/20.
@@ -92,6 +96,51 @@ class TextAndGraphicUpdateOperation extends Task {
}
}
+ void updateTargetStateWithErrorState(@NonNull TextAndGraphicState errorState){
+ if (Objects.equals(errorState.getTextField1(), updatedState.getTextField1())){
+ updatedState.setTextField1(currentScreenData.getTextField1());
+ }
+ if (Objects.equals(errorState.getTextField2(), updatedState.getTextField2())){
+ updatedState.setTextField2(currentScreenData.getTextField2());
+ }
+ if (Objects.equals(errorState.getTextField3(), updatedState.getTextField3())){
+ updatedState.setTextField3(currentScreenData.getTextField3());
+ }
+ if (Objects.equals(errorState.getTextField4(), updatedState.getTextField4())){
+ updatedState.setTextField4(currentScreenData.getTextField4());
+ }
+ if (Objects.equals(errorState.getMediaTrackTextField(), updatedState.getMediaTrackTextField())){
+ updatedState.setMediaTrackTextField(currentScreenData.getMediaTrackTextField());
+ }
+ if (Objects.equals(errorState.getTitle(), updatedState.getTitle())){
+ updatedState.setTitle(currentScreenData.getTitle());
+ }
+ if (Objects.equals(errorState.getPrimaryGraphic(), updatedState.getPrimaryGraphic())){
+ updatedState.setPrimaryGraphic(currentScreenData.getPrimaryGraphic());
+ }
+ if (Objects.equals(errorState.getSecondaryGraphic(), updatedState.getSecondaryGraphic())){
+ updatedState.setSecondaryGraphic(currentScreenData.getSecondaryGraphic());
+ }
+ if (Objects.equals(errorState.getTextAlignment(), updatedState.getTextAlignment())){
+ updatedState.setTextAlignment(currentScreenData.getTextAlignment());
+ }
+ if (Objects.equals(errorState.getTextField1Type(), updatedState.getTextField1Type())){
+ updatedState.setTextField1Type(currentScreenData.getTextField1Type());
+ }
+ if (Objects.equals(errorState.getTextField2Type(), updatedState.getTextField2Type())){
+ updatedState.setTextField2Type(currentScreenData.getTextField2Type());
+ }
+ if (Objects.equals(errorState.getTextField3Type(), updatedState.getTextField3Type())){
+ updatedState.setTextField3Type(currentScreenData.getTextField3Type());
+ }
+ if (Objects.equals(errorState.getTextField4Type(), updatedState.getTextField4Type())){
+ updatedState.setTextField4Type(currentScreenData.getTextField4Type());
+ }
+ if (Objects.equals(errorState.getTemplateConfiguration(), updatedState.getTemplateConfiguration())){
+ updatedState.setTemplateConfiguration(currentScreenData.getTemplateConfiguration());
+ }
+ }
+
void updateGraphicsAndShow(Show show) {
if (!shouldUpdatePrimaryImage() && !shouldUpdateSecondaryImage()) {
DebugTool.logInfo(TAG, "No images to send, sending text");
@@ -129,7 +178,6 @@ class TextAndGraphicUpdateOperation extends Task {
finishOperation(success);
}
});
-
}
});
}
@@ -144,7 +192,7 @@ class TextAndGraphicUpdateOperation extends Task {
updateCurrentScreenDataFromShow(show);
} else {
DebugTool.logInfo(TAG, "Text and Graphic Show failed");
- currentScreenDataUpdateListener.onError();
+ currentScreenDataUpdateListener.onError(updatedState);
}
listener.onComplete(response.getSuccess());
@@ -154,11 +202,10 @@ class TextAndGraphicUpdateOperation extends Task {
internalInterface.get().sendRPC(show);
} else {
DebugTool.logInfo(TAG, "ISdl is null Text and Graphic update failed");
- currentScreenDataUpdateListener.onError();
+ currentScreenDataUpdateListener.onError(updatedState);
finishOperation(false);
return;
}
-
}
@SuppressWarnings("deprecation")
@@ -171,7 +218,7 @@ class TextAndGraphicUpdateOperation extends Task {
updateCurrentScreenDataFromSetDisplayLayout(setLayout);
} else {
DebugTool.logInfo(TAG, "Text and Graphic SetDisplayLayout failed");
- currentScreenDataUpdateListener.onError();
+ currentScreenDataUpdateListener.onError(updatedState);
}
listener.onComplete(response.getSuccess());
}
@@ -180,7 +227,7 @@ class TextAndGraphicUpdateOperation extends Task {
internalInterface.get().sendRPC(setLayout);
} else {
DebugTool.logInfo(TAG, "ISdl is null Text and Graphic update failed");
- currentScreenDataUpdateListener.onError();
+ currentScreenDataUpdateListener.onError(updatedState);
finishOperation(false);
return;
}
@@ -586,6 +633,9 @@ class TextAndGraphicUpdateOperation extends Task {
if (show.getSecondaryGraphic() != null) {
currentScreenData.setSecondaryGraphic(updatedState.getSecondaryGraphic());
}
+ if (show.getTemplateConfiguration() != null) {
+ currentScreenData.setTemplateConfiguration(updatedState.getTemplateConfiguration());
+ }
if (currentScreenDataUpdateListener != null) {
currentScreenDataUpdateListener.onUpdate(currentScreenData);
}
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/AddCommand.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/AddCommand.java
index e46d39339..0e00a14aa 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/AddCommand.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/AddCommand.java
@@ -86,15 +86,15 @@ import java.util.List;
* <td>SmartDeviceLink 1.0</td>
* <tr>
* <td>menuParams</td>
- * <td>ButtonName</td>
+ * <td>MenuParams</td>
* <td>Name of the button to unsubscribe.</td>
- * <td>Y</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 1.0</td>
* </tr>
* <tr>
* <td>vrCommands</td>
- * <td>String</td>
+ * <td>List<String></td>
* <td><p>An array of strings to be used as VR synonyms for this command.</p> <p>If this array is provided, it may not be empty.</p></td>
* <td>N</td>
* <td>minsize:1; maxsize:100</td>
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/AddSubMenu.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/AddSubMenu.java
index fcd93d42e..6be1f4c03 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/AddSubMenu.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/AddSubMenu.java
@@ -94,7 +94,7 @@ import java.util.Hashtable;
* <td>menuLayout</td>
* <td>MenuLayout</td>
* <td>Sets the layout of the submenu screen.</td>
- * <td></td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 6.0</td>
* </tr>
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/BodyInformation.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/BodyInformation.java
index 08819aa09..8d016c15d 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/BodyInformation.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/BodyInformation.java
@@ -55,13 +55,6 @@ import java.util.List;
* <th>Version</th>
* </tr>
* <tr>
- * <td>parkBrakeActive</td>
- * <td>Boolean</td>
- * <td>true</td>
- * <td>Describes, if the park break is active. The information about the park brake: - true, if active - false if not.</td>
- * <td>SmartDeviceLink 2.0</td>
- * </tr>
- * <tr>
* <td>ignitionStableStatus</td>
* <td>IgnitionStableStatus</td>
* <td>true</td>
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/MenuParams.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/MenuParams.java
index 2f6b3d712..d62ef079d 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/MenuParams.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/MenuParams.java
@@ -44,7 +44,7 @@ import java.util.Hashtable;
* <tr>
* <th>Name</th>
* <th>Type</th>
- * <th>Description</th>
+ * <th>Description</th>
* <th>Req.</th>
* <th>SmartDeviceLink Ver. Available</th>
* </tr>
@@ -57,8 +57,8 @@ import java.util.Hashtable;
* <li>Min: 0</li>
* <li>Max: 2000000000</li>
* </ul>
- * </td>
- * <th></th>
+ * </td>
+ * <td>N</td>
* <td>SmartDeviceLink 1.0</td>
* </tr>
* <tr>
@@ -72,8 +72,8 @@ import java.util.Hashtable;
* <li>If position is greater or equal than the number of items in the parent Command Menu, the sub menu will be appended to the end of that Command Menu.</li>
* <li>If this element is omitted, the entry will be added at the end of the parent menu.</li>
* </ul>
- * </td>
- * <th></th>
+ * </td>
+ * <td>N</td>
* <td>SmartDeviceLink 1.0</td>
* </tr>
* <tr>
@@ -84,8 +84,8 @@ import java.util.Hashtable;
* <li>Min: 1</li>
* <li>Max: 100</li>
* </ul>
- * </td>
- * <th></th>
+ * </td>
+ * <td>Y</td>
* <td>SmartDeviceLink 1.0</td>
* </tr>
* <tr>
diff --git a/base/src/main/java/com/smartdevicelink/proxy/rpc/OnVehicleData.java b/base/src/main/java/com/smartdevicelink/proxy/rpc/OnVehicleData.java
index 09608fb9a..800141ace 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/OnVehicleData.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/OnVehicleData.java
@@ -93,7 +93,7 @@ import java.util.List;
* </tr>
* <tr>
* <td>fuelLevel</td>
- * <td>Boolean</td>
+ * <td>Double</td>
* <td>The fuel level in the tank (percentage). This parameter is deprecated starting RPC Spec7.0, please see fuelRange.</td>
* <td>N</td>
* <td>Subscribable</td>
@@ -101,7 +101,7 @@ import java.util.List;
* </tr>
* <tr>
* <td>fuelLevel_State</td>
- * <td>Boolean</td>
+ * <td>ComponentVolumeStatus</td>
* <td>The fuel level state. This parameter is deprecated starting RPC Spec 7.0, please see fuelRange.</td>
* <td>N</td>
* <td>Subscribable</td>
@@ -109,7 +109,7 @@ import java.util.List;
* </tr>
* <tr>
* <td>fuelRange</td>
- * <td>Boolean</td>
+ * <td>List<FuelRange></td>
* <td>The fuel type, estimated range in KM, fuel level/capacity and fuel level state for the vehicle. See struct FuelRange for details.</td>
* <td>N</td>
* <td>{"array_min_size": 0, "array_max_size": 100}</td>
@@ -143,7 +143,7 @@ import java.util.List;
* <td>gearStatus</td>
* <td>GearStatus</td>
* <td>See GearStatus</td>
- * <td>N</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 7.0.0</td>
* </tr>
@@ -151,7 +151,7 @@ import java.util.List;
* <td>prndl</td>
* <td>PRNDL</td>
* <td>See PRNDL. This parameter is deprecated and it is now covered in `gearStatus`</td>
- * <td>N</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 7.0.0</td>
* </tr>
@@ -304,15 +304,15 @@ import java.util.List;
* <td>handsOffSteering</td>
* <td>Boolean</td>
* <td>To indicate whether driver hands are off the steering wheel</td>
- * <td>N</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 7.0.0</td>
* </tr>
* <tr>
* <td>windowStatus</td>
- * <td>Boolean</td>
+ * <td>List<WindowStatus></td>
* <td>See WindowStatus</td>
- * <td>N</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 7.0.0</td>
* </tr>
@@ -330,7 +330,7 @@ import java.util.List;
* <td>stabilityControlsStatus</td>
* <td>StabilityControlsStatus</td>
* <td>See StabilityControlsStatus</td>
- * <td>N</td>
+ * <td>N</td>
* <td></td>
* <td>SmartDeviceLink 7.0.0</td>
* </tr>
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 1e091beb6..2eaa41e56 100644
--- a/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java
+++ b/base/src/main/java/com/smartdevicelink/proxy/rpc/Show.java
@@ -120,8 +120,8 @@ import java.util.List;
* <td>Text value for MediaClock field. Has to be properly formatted by Mobile App according to the module's capabilities. If this text is set, any automatic media clock updates previously set with SetMediaClockTimer will be stopped.</td>
* <td>N</td>
* <td>{"string_min_length": 0, "string_max_length": 500}</td>
- * <td>SmartDeviceLink 1.0.0
- * <br>
+ * <td>SmartDeviceLink 1.0.0
+ * <br>
* <br>
* Deprecated in SmartDeviceLink 7.1.0</td>
* </tr>
@@ -151,7 +151,7 @@ import java.util.List;
* </tr>
* <tr>
* <td>softButtons</td>
- * <td>SoftButton</td>
+ * <td>List<SoftButton></td>
* <td>Soft buttons as defined by the App</td>
* <td>N</td>
* <td><p>If omitted on supported displays, the currently displayed SoftButton values will not change.</p>Array Minsize: 0; Array Maxsize: 8</td>
@@ -168,7 +168,7 @@ import java.util.List;
* <tr>
* <td>templateTitle</td>
* <td>String</td>
- * <td>The title of the new template that will be displayed.</td>
+ * <td>The title of the new template that will be displayed.</td>
* <td>N</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>SmartDeviceLink 6.0.0</td>
diff --git a/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java b/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java
index 4a7314ad7..7a2a6067e 100644
--- a/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java
+++ b/javaSE/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 = "5.5.0";
+ public static final String VERSION_NAME = "5.6.0";
} \ No newline at end of file
diff --git a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
index 2c31c848a..e9e1fd136 100644
--- a/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
+++ b/javaSE/javaSE/src/main/java/com/smartdevicelink/managers/file/filetypes/SdlArtwork.java
@@ -160,7 +160,7 @@ public class SdlArtwork extends SdlFile implements Cloneable {
public SdlArtwork clone() {
SdlArtwork artwork = (SdlArtwork) super.clone();
if (artwork != null) {
- artwork.imageRPC = artwork.createImageRPC();
+ artwork.imageRPC = null;
return artwork;
}
return null;