summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Grover <joeygrover@gmail.com>2017-10-04 15:45:42 -0400
committerJoey Grover <joeygrover@gmail.com>2017-10-04 15:45:42 -0400
commit8d743df8b19898b34a7c4cbe98971e4ad830b4c3 (patch)
treec685c7e53890b670f3f68bac64f923297a408c75
parentf796e725063b539c9ab1563d47061fa6de0d51a2 (diff)
parentbf2f2b405ca10e777832b32eadfe14ed21d6a74d (diff)
downloadsdl_android-8d743df8b19898b34a7c4cbe98971e4ad830b4c3.tar.gz
Merge branch 'develop' of https://github.com/smartdevicelink/sdl_android into feature/issue_469_update
# Conflicts: # sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
-rw-r--r--.travis.yml9
-rw-r--r--sdl_android/build.gradle2
-rw-r--r--sdl_android/src/androidTest/assets/json/ButtonPress.json15
-rw-r--r--sdl_android/src/androidTest/assets/json/GetInteriorVehicleData.json38
-rw-r--r--sdl_android/src/androidTest/assets/json/SetInteriorVehicleData.json56
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/protocol/WiProProtocolTests.java5
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java152
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/Validator.java497
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/encoder/EncoderUtilsTest.java116
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java24
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java56
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlCapabilitiesTests.java160
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlDataTests.java130
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ModuleDataTests.java95
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/NavigationCapabilityTests.java69
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/PhoneCapabilityTests.java64
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlCapabilitiesTests.java112
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlDataTests.java124
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RdsDataTests.java101
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RemoteControlCapabilitiesTests.java131
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/SystemCapabilityTests.java51
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/TemperatureTests.java72
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppHmiTypeTests.java6
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ButtonNameTests.java77
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/DefrostZoneTests.java79
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ModuleTypeTests.java71
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioBandTests.java75
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioStateTests.java79
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java10
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/SystemCapabilityTypeTests.java115
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VentilationModeTests.java79
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/notifications/OnInteriorVehicleDataTests.java69
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ButtonPressTests.java113
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/GetInteriorVehicleDataTests.java105
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/SetInteriorVehicleDataTests.java102
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ButtonPressResponseTest.java74
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/GetInteriorVehicleDataResponseTests.java110
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/SetInteriorVehicleDataResponseTests.java104
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/security/SdlSecurityBaseTest.java2
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/AbstractPacketizerTests.java3
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/RTPH264PacketizerTest.java881
-rw-r--r--sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/StreamPacketizerTests.java461
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java4
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java11
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java110
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java107
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java50
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/protocol/AbstractProtocol.java7
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/protocol/IProtocolListener.java5
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/protocol/ProtocolMessage.java8
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java29
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java6
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java1919
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java14
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IAudioStreamListener.java71
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java12
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/ISdl.java116
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IVideoStreamListener.java90
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPress.java94
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPressResponse.java28
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlCapabilities.java280
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlData.java106
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleData.java79
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleDataResponse.java70
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/HMICapabilities.java13
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ImageResolution.java6
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ModuleData.java75
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/OnInteriorVehicleData.java47
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlCapabilities.java236
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlData.java220
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RdsData.java180
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RemoteControlCapabilities.java82
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleData.java51
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleDataResponse.java47
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SystemCapability.java5
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/Temperature.java56
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/VideoStreamingFormat.java11
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/AppHMIType.java7
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ButtonName.java23
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/DefrostZone.java17
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ModuleType.java15
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioBand.java16
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioState.java20
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/Result.java11
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/TemperatureUnit.java14
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/VentilationMode.java17
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingCodec.java49
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingLPCMParams.java64
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingParams.java55
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/RTPH264Packetizer.java505
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java155
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/streaming/VideoStreamingParameters.java6
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java13
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java228
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java55
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java3
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java7
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/util/AndroidTools.java29
-rw-r--r--sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java141
99 files changed, 9547 insertions, 842 deletions
diff --git a/.travis.yml b/.travis.yml
index 5df5d6198..fb7fc4dbe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,19 +5,20 @@ android:
components:
# use the latest revision of Android SDK Tools
- tools
- - platform-tools
- tools
+ - platform-tools
- ndk-bundle
# The BuildTools version used by your project
- - build-tools-25.0.2
+ - build-tools-26.0.1
# The SDK version used to compile your project
- - android-22
+ - android-26
+ - android-22 #For emulator
# Specify at least one system image,
# if you need to run emulator(s) during your tests
- sys-img-armeabi-v7a-android-22
- # - sys-img-x86-android-17
+ # - sys-img-x86-android-26
# Android Support Repos
- extra-android-m2repository
diff --git a/sdl_android/build.gradle b/sdl_android/build.gradle
index ad04cab31..13c53c692 100644
--- a/sdl_android/build.gradle
+++ b/sdl_android/build.gradle
@@ -1,7 +1,7 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 22
+ compileSdkVersion 26
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 8
diff --git a/sdl_android/src/androidTest/assets/json/ButtonPress.json b/sdl_android/src/androidTest/assets/json/ButtonPress.json
new file mode 100644
index 000000000..e74e857be
--- /dev/null
+++ b/sdl_android/src/androidTest/assets/json/ButtonPress.json
@@ -0,0 +1,15 @@
+{
+ "request":{
+ "name":"ButtonPress",
+ "correlationID":215,
+ "parameters":{
+ "buttonName":"OK",
+ "buttonPressMode":"LONG",
+ "moduleType":"CLIMATE"
+ }
+ },
+ "response":{
+ "name":"ButtonPressResponse",
+ "correlationID":216
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/assets/json/GetInteriorVehicleData.json b/sdl_android/src/androidTest/assets/json/GetInteriorVehicleData.json
new file mode 100644
index 000000000..7000d2918
--- /dev/null
+++ b/sdl_android/src/androidTest/assets/json/GetInteriorVehicleData.json
@@ -0,0 +1,38 @@
+{
+ "request":{
+ "name":"GetInteriorVehicleData",
+ "correlationID":101,
+ "parameters":{
+ "subscribe":true,
+ "moduleType":"CLIMATE"
+ }
+ },
+ "response":{
+ "name":"GetInteriorVehicleDataResponse",
+ "correlationID":102,
+ "parameters":{
+ "isSubscribed":true,
+ "moduleData":{
+ "moduleType":"CLIMATE",
+ "climateControlData":{
+ "circulateAirEnable":true,
+ "ventilationMode":"UPPER",
+ "acEnable":true,
+ "currentTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "acMaxEnable":true,
+ "desiredTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "dualModeEnable":true,
+ "autoModeEnable":true,
+ "fanSpeed":100,
+ "defrostZone":"FRONT"
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/assets/json/SetInteriorVehicleData.json b/sdl_android/src/androidTest/assets/json/SetInteriorVehicleData.json
new file mode 100644
index 000000000..9bcdc01dc
--- /dev/null
+++ b/sdl_android/src/androidTest/assets/json/SetInteriorVehicleData.json
@@ -0,0 +1,56 @@
+{
+ "request":{
+ "name":"SetInteriorVehicleData",
+ "correlationID":126,
+ "parameters":{
+ "moduleData":{
+ "moduleType":"CLIMATE",
+ "climateControlData":{
+ "circulateAirEnable":true,
+ "ventilationMode":"BOTH",
+ "acEnable":true,
+ "currentTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "acMaxEnable":true,
+ "desiredTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "dualModeEnable":true,
+ "autoModeEnable":true,
+ "fanSpeed":100,
+ "defrostZone":"ALL"
+ }
+ }
+ }
+ },
+ "response":{
+ "name":"SetInteriorVehicleDataResponse",
+ "correlationID":127,
+ "parameters":{
+ "moduleData":{
+ "moduleType":"CLIMATE",
+ "climateControlData":{
+ "circulateAirEnable":true,
+ "ventilationMode":"BOTH",
+ "acEnable":true,
+ "currentTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "acMaxEnable":true,
+ "desiredTemperature":{
+ "unit":"CELSIUS",
+ "value":100.0
+ },
+ "dualModeEnable":true,
+ "autoModeEnable":true,
+ "fanSpeed":100,
+ "defrostZone":"ALL"
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/protocol/WiProProtocolTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/protocol/WiProProtocolTests.java
index f8cae95f4..1055f5deb 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/protocol/WiProProtocolTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/protocol/WiProProtocolTests.java
@@ -16,6 +16,7 @@ import junit.framework.Assert;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
+import java.util.List;
/**
* This is a unit test class for the SmartDeviceLink library project class :
@@ -37,7 +38,7 @@ public class WiProProtocolTests extends AndroidTestCase {
@Override
public void onProtocolSessionStarted(SessionType sessionType,byte sessionID, byte version, String correlationID, int hashID,boolean isEncrypted){}
@Override
- public void onProtocolSessionNACKed(SessionType sessionType,byte sessionID, byte version, String correlationID) {}
+ public void onProtocolSessionNACKed(SessionType sessionType,byte sessionID, byte version, String correlationID, List<String> rejectedParams) {}
@Override
public void onProtocolSessionEnded(SessionType sessionType,byte sessionID, String correlationID) {}
@Override
@@ -76,7 +77,7 @@ public class WiProProtocolTests extends AndroidTestCase {
@Override
public void onProtocolSessionStarted(SessionType sessionType,byte sessionID, byte version, String correlationID, int hashID,boolean isEncrypted){}
@Override
- public void onProtocolSessionNACKed(SessionType sessionType,byte sessionID, byte version, String correlationID) {}
+ public void onProtocolSessionNACKed(SessionType sessionType,byte sessionID, byte version, String correlationID, List<String> rejectedParams) {}
@Override
public void onProtocolSessionEnded(SessionType sessionType,byte sessionID, String correlationID) {}
@Override
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
index 782692d69..46f4e89be 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/Test.java
@@ -6,6 +6,8 @@ import com.smartdevicelink.proxy.TTSChunkFactory;
import com.smartdevicelink.proxy.rpc.AudioPassThruCapabilities;
import com.smartdevicelink.proxy.rpc.ButtonCapabilities;
import com.smartdevicelink.proxy.rpc.Choice;
+import com.smartdevicelink.proxy.rpc.ClimateControlCapabilities;
+import com.smartdevicelink.proxy.rpc.ClimateControlData;
import com.smartdevicelink.proxy.rpc.Coordinate;
import com.smartdevicelink.proxy.rpc.DIDResult;
import com.smartdevicelink.proxy.rpc.DeviceInfo;
@@ -19,11 +21,18 @@ import com.smartdevicelink.proxy.rpc.ImageResolution;
import com.smartdevicelink.proxy.rpc.KeyboardProperties;
import com.smartdevicelink.proxy.rpc.LocationDetails;
import com.smartdevicelink.proxy.rpc.MenuParams;
+import com.smartdevicelink.proxy.rpc.ModuleData;
+import com.smartdevicelink.proxy.rpc.NavigationCapability;
import com.smartdevicelink.proxy.rpc.MetadataTags;
import com.smartdevicelink.proxy.rpc.OasisAddress;
import com.smartdevicelink.proxy.rpc.ParameterPermissions;
import com.smartdevicelink.proxy.rpc.PermissionItem;
+import com.smartdevicelink.proxy.rpc.PhoneCapability;
import com.smartdevicelink.proxy.rpc.PresetBankCapabilities;
+import com.smartdevicelink.proxy.rpc.RadioControlCapabilities;
+import com.smartdevicelink.proxy.rpc.RadioControlData;
+import com.smartdevicelink.proxy.rpc.RdsData;
+import com.smartdevicelink.proxy.rpc.RemoteControlCapabilities;
import com.smartdevicelink.proxy.rpc.Rectangle;
import com.smartdevicelink.proxy.rpc.ScreenParams;
import com.smartdevicelink.proxy.rpc.SdlMsgVersion;
@@ -32,6 +41,7 @@ import com.smartdevicelink.proxy.rpc.SoftButtonCapabilities;
import com.smartdevicelink.proxy.rpc.StartTime;
import com.smartdevicelink.proxy.rpc.SystemCapability;
import com.smartdevicelink.proxy.rpc.TTSChunk;
+import com.smartdevicelink.proxy.rpc.Temperature;
import com.smartdevicelink.proxy.rpc.TextField;
import com.smartdevicelink.proxy.rpc.TouchCoord;
import com.smartdevicelink.proxy.rpc.TouchEvent;
@@ -55,6 +65,7 @@ import com.smartdevicelink.proxy.rpc.enums.CarModeStatus;
import com.smartdevicelink.proxy.rpc.enums.CharacterSet;
import com.smartdevicelink.proxy.rpc.enums.CompassDirection;
import com.smartdevicelink.proxy.rpc.enums.ComponentVolumeStatus;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
import com.smartdevicelink.proxy.rpc.enums.DeviceLevelStatus;
import com.smartdevicelink.proxy.rpc.enums.Dimension;
import com.smartdevicelink.proxy.rpc.enums.DisplayType;
@@ -77,10 +88,13 @@ import com.smartdevicelink.proxy.rpc.enums.Language;
import com.smartdevicelink.proxy.rpc.enums.LayoutMode;
import com.smartdevicelink.proxy.rpc.enums.LockScreenStatus;
import com.smartdevicelink.proxy.rpc.enums.MediaClockFormat;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
import com.smartdevicelink.proxy.rpc.enums.PowerModeQualificationStatus;
import com.smartdevicelink.proxy.rpc.enums.PowerModeStatus;
import com.smartdevicelink.proxy.rpc.enums.PrerecordedSpeech;
import com.smartdevicelink.proxy.rpc.enums.PrimaryAudioSource;
+import com.smartdevicelink.proxy.rpc.enums.RadioBand;
+import com.smartdevicelink.proxy.rpc.enums.RadioState;
import com.smartdevicelink.proxy.rpc.enums.RequestType;
import com.smartdevicelink.proxy.rpc.enums.SamplingRate;
import com.smartdevicelink.proxy.rpc.enums.SoftButtonType;
@@ -89,6 +103,7 @@ import com.smartdevicelink.proxy.rpc.enums.SystemAction;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.enums.SystemContext;
import com.smartdevicelink.proxy.rpc.enums.TBTState;
+import com.smartdevicelink.proxy.rpc.enums.TemperatureUnit;
import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
import com.smartdevicelink.proxy.rpc.enums.TextFieldName;
import com.smartdevicelink.proxy.rpc.enums.MetadataType;
@@ -100,6 +115,7 @@ import com.smartdevicelink.proxy.rpc.enums.VehicleDataNotificationStatus;
import com.smartdevicelink.proxy.rpc.enums.VehicleDataResultCode;
import com.smartdevicelink.proxy.rpc.enums.VehicleDataStatus;
import com.smartdevicelink.proxy.rpc.enums.VehicleDataType;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
import com.smartdevicelink.proxy.rpc.enums.VideoStreamingCodec;
import com.smartdevicelink.proxy.rpc.enums.VideoStreamingProtocol;
import com.smartdevicelink.proxy.rpc.enums.VrCapabilities;
@@ -215,13 +231,30 @@ public class Test {
public static final VehicleDataNotificationStatus GENERAL_VEHICLEDATANOTIFICATIONSTATUS = VehicleDataNotificationStatus.NORMAL;
public static final AppInterfaceUnregisteredReason GENERAL_APPINTERFACEUNREGISTEREDREASON = AppInterfaceUnregisteredReason.BLUETOOTH_OFF;
public static final SystemCapabilityType GENERAL_SYSTEMCAPABILITYTYPE = SystemCapabilityType.NAVIGATION;
+ public static final NavigationCapability GENERAL_NAVIGATIONCAPABILITY = new NavigationCapability();
+ public static final PhoneCapability GENERAL_PHONECAPABILITY = new PhoneCapability();
+ public static final RemoteControlCapabilities GENERAL_REMOTECONTROLCAPABILITIES = new RemoteControlCapabilities();
public static final SystemCapability GENERAL_SYSTEMCAPABILITY = new SystemCapability();
public static final VideoStreamingProtocol GENERAL_VIDEOSTREAMINGPROTOCOL = VideoStreamingProtocol.RAW;
public static final VideoStreamingCodec GENERAL_VIDEOSTREAMINGCODEC = VideoStreamingCodec.H264;
public static final VideoStreamingCapability GENERAL_VIDEOSTREAMINGCAPABILITY = new VideoStreamingCapability();
public static final VideoStreamingFormat GENERAL_VIDEOSTREAMINGFORMAT = new VideoStreamingFormat();
+
+ public static final ModuleType GENERAL_MODULETYPE = ModuleType.CLIMATE;
+ public static final Temperature GENERAL_TEMPERATURE = new Temperature();
+ public static final TemperatureUnit GENERAL_TEMPERATUREUNIT = TemperatureUnit.CELSIUS;
+ public static final DefrostZone GENERAL_DEFROSTZONE = DefrostZone.ALL;
+ public static final VentilationMode GENERAL_VENTILATIONMODE = VentilationMode.BOTH;
+ public static final RadioBand GENERAL_RADIOBAND = RadioBand.AM;
+ public static final ClimateControlData GENERAL_CLIMATECONTROLDATA = new ClimateControlData();
+ public static final RdsData GENERAL_RDSDATA = new RdsData();
+ public static final RadioState GENERAL_RADIOSTATE = RadioState.ACQUIRED;
+ public static final RadioControlData GENERAL_RADIOCONTROLDATA = new RadioControlData();
+ public static final ModuleData GENERAL_MODULEDATA = new ModuleData();
+ public static final ClimateControlCapabilities GENERAL_CLIMATECONTROLCAPABILITIES = new ClimateControlCapabilities();
+ public static final RadioControlCapabilities GENERAL_RADIOCONTROLCAPABILITIES = new RadioControlCapabilities();
+
public static final HMICapabilities GENERAL_HMICAPABILITIES = new HMICapabilities();
-
public static final MetadataTags GENERAL_METADATASTRUCT = new MetadataTags();
public static final Rectangle GENERAL_RECTANGLE = new Rectangle();
@@ -255,7 +288,11 @@ public class Test {
public static final List<SoftButtonCapabilities> GENERAL_SOFTBUTTONCAPABILITIES_LIST = new ArrayList<SoftButtonCapabilities>(1);
public static final List<AudioPassThruCapabilities> GENERAL_AUDIOPASSTHRUCAPABILITIES_LIST = new ArrayList<AudioPassThruCapabilities>(1);
public static final List<VideoStreamingFormat> GENERAL_VIDEOSTREAMINGFORMAT_LIST = new ArrayList<VideoStreamingFormat>(2);
-
+ public static final List<DefrostZone> GENERAL_DEFROSTZONE_LIST = Arrays.asList(new DefrostZone[]{DefrostZone.FRONT, DefrostZone.REAR});
+ public static final List<VentilationMode> GENERAL_VENTILATIONMODE_LIST = Arrays.asList(new VentilationMode[]{VentilationMode.LOWER, VentilationMode.UPPER});
+ public static final List<ClimateControlCapabilities> GENERAL_CLIMATECONTROLCAPABILITIES_LIST = new ArrayList<ClimateControlCapabilities>(1);
+ public static final List<RadioControlCapabilities> GENERAL_RADIOCONTROLCAPABILITIES_LIST = new ArrayList<RadioControlCapabilities>(1);
+
public static final JSONArray JSON_TURNS = new JSONArray();
public static final JSONArray JSON_CHOICES = new JSONArray();
public static final JSONArray JSON_HMILEVELS = new JSONArray();
@@ -271,8 +308,9 @@ public class Test {
public static final JSONArray JSON_BUTTONCAPABILITIES = new JSONArray();
public static final JSONArray JSON_SOFTBUTTONCAPABILITIES = new JSONArray();
public static final JSONArray JSON_AUDIOPASSTHRUCAPABILITIES = new JSONArray();
+ public static final JSONArray JSON_RADIOCONTROLCAPABILITIES = new JSONArray();
+ public static final JSONArray JSON_CLIMATECONTROLCAPABILITIES = new JSONArray();
public static final JSONArray JSON_TEXTFIELDTYPES = new JSONArray();
-
public static final JSONObject JSON_TURN = new JSONObject();
public static final JSONObject JSON_IMAGE = new JSONObject();
public static final JSONObject JSON_CHOICE = new JSONObject();
@@ -296,15 +334,52 @@ public class Test {
public static final JSONObject JSON_PARAMETERPERMISSIONS = new JSONObject();
public static final JSONObject JSON_PRESETBANKCAPABILITIES = new JSONObject();
public static final JSONObject JSON_TOUCHEVENTCAPABILITIES = new JSONObject();
-
+
static {
GENERAL_TOUCHEVENTCAPABILITIES.setDoublePressAvailable(GENERAL_BOOLEAN);
GENERAL_TOUCHEVENTCAPABILITIES.setMultiTouchAvailable(GENERAL_BOOLEAN);
GENERAL_TOUCHEVENTCAPABILITIES.setPressAvailable(GENERAL_BOOLEAN);
GENERAL_IMAGERESOLUTION.setResolutionHeight(GENERAL_INT);
- GENERAL_IMAGERESOLUTION.setResolutionWidth(GENERAL_INT);
-
+ GENERAL_IMAGERESOLUTION.setResolutionWidth(GENERAL_INT);
+
+ GENERAL_TEMPERATURE.setUnit(GENERAL_TEMPERATUREUNIT);
+ GENERAL_TEMPERATURE.setValue(GENERAL_FLOAT);
+
+ GENERAL_CLIMATECONTROLDATA.setFanSpeed(GENERAL_INT);
+ GENERAL_CLIMATECONTROLDATA.setCurrentTemperature(GENERAL_TEMPERATURE);
+ GENERAL_CLIMATECONTROLDATA.setDesiredTemperature(GENERAL_TEMPERATURE);
+ GENERAL_CLIMATECONTROLDATA.setAcEnable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLDATA.setCirculateAirEnable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLDATA.setAutoModeEnable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLDATA.setDualModeEnable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLDATA.setAcMaxEnable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLDATA.setDefrostZone(GENERAL_DEFROSTZONE);
+ GENERAL_CLIMATECONTROLDATA.setVentilationMode(GENERAL_VENTILATIONMODE);
+
+ GENERAL_RDSDATA.setProgramService(GENERAL_STRING);
+ GENERAL_RDSDATA.setRadioText(GENERAL_STRING);
+ GENERAL_RDSDATA.setClockText(GENERAL_STRING);
+ GENERAL_RDSDATA.setProgramIdentification(GENERAL_STRING);
+ GENERAL_RDSDATA.setRegion(GENERAL_STRING);
+ GENERAL_RDSDATA.setTrafficProgram(GENERAL_BOOLEAN);
+ GENERAL_RDSDATA.setTrafficAnnouncement(GENERAL_BOOLEAN);
+ GENERAL_RDSDATA.setProgramType(GENERAL_INT);
+
+ GENERAL_RADIOCONTROLDATA.setFrequencyInteger(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setFrequencyFraction(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setBand(GENERAL_RADIOBAND);
+ GENERAL_RADIOCONTROLDATA.setRdsData(GENERAL_RDSDATA);
+ GENERAL_RADIOCONTROLDATA.setAvailableHDs(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setHdChannel(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setSignalStrength(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setSignalChangeThreshold(GENERAL_INT);
+ GENERAL_RADIOCONTROLDATA.setRadioEnable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLDATA.setState(GENERAL_RADIOSTATE);
+
+ GENERAL_MODULEDATA.setModuleType(GENERAL_MODULETYPE);
+ GENERAL_MODULEDATA.setClimateControlData(GENERAL_CLIMATECONTROLDATA);
+
GENERAL_CHOICE.setMenuName(GENERAL_STRING);
GENERAL_CHOICE.setSecondaryText(GENERAL_STRING);
GENERAL_CHOICE.setTertiaryText(GENERAL_STRING);
@@ -486,6 +561,11 @@ public class Test {
GENERAL_SYSTEMCAPABILITY.setSystemCapabilityType(GENERAL_SYSTEMCAPABILITYTYPE);
+ GENERAL_NAVIGATIONCAPABILITY.setSendLocationEnabled(GENERAL_BOOLEAN);
+ GENERAL_NAVIGATIONCAPABILITY.setWayPointsEnabled(GENERAL_BOOLEAN);
+
+ GENERAL_PHONECAPABILITY.setDialNumberEnabled(GENERAL_BOOLEAN);
+
GENERAL_VIDEOSTREAMINGFORMAT.setProtocol(GENERAL_VIDEOSTREAMINGPROTOCOL);
GENERAL_VIDEOSTREAMINGFORMAT.setCodec(GENERAL_VIDEOSTREAMINGCODEC);
@@ -496,6 +576,36 @@ public class Test {
GENERAL_VIDEOSTREAMINGCAPABILITY.setPreferredResolution(GENERAL_IMAGERESOLUTION);
GENERAL_VIDEOSTREAMINGCAPABILITY.setSupportedFormats(GENERAL_VIDEOSTREAMINGFORMAT_LIST);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setModuleName(GENERAL_STRING);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setFanSpeedAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setDesiredTemperatureAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setAcEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setAcMaxEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setCirculateAirEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setAutoModeEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setDualModeEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setDefrostZoneAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setDefrostZone(GENERAL_DEFROSTZONE_LIST);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setVentilationModeAvailable(GENERAL_BOOLEAN);
+ GENERAL_CLIMATECONTROLCAPABILITIES.setVentilationMode(GENERAL_VENTILATIONMODE_LIST);
+ GENERAL_CLIMATECONTROLCAPABILITIES_LIST.add(GENERAL_CLIMATECONTROLCAPABILITIES);
+
+ GENERAL_RADIOCONTROLCAPABILITIES.setModuleName(GENERAL_STRING);
+ GENERAL_RADIOCONTROLCAPABILITIES.setRadioEnableAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setRadioBandAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setRadioFrequencyAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setHdChannelAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setRdsDataAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setAvailableHDsAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setStateAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setSignalStrengthAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES.setSignalChangeThresholdAvailable(GENERAL_BOOLEAN);
+ GENERAL_RADIOCONTROLCAPABILITIES_LIST.add(GENERAL_RADIOCONTROLCAPABILITIES);
+
+ GENERAL_REMOTECONTROLCAPABILITIES.setButtonCapabilities(GENERAL_BUTTONCAPABILITIES_LIST);
+ GENERAL_REMOTECONTROLCAPABILITIES.setClimateControlCapabilities(GENERAL_CLIMATECONTROLCAPABILITIES_LIST);
+ GENERAL_REMOTECONTROLCAPABILITIES.setRadioControlCapabilities(GENERAL_RADIOCONTROLCAPABILITIES_LIST);
+
GENERAL_HMICAPABILITIES.setNavigationAvilable(GENERAL_BOOLEAN);
GENERAL_HMICAPABILITIES.setVideoStreamingAvailable(GENERAL_BOOLEAN);
GENERAL_HMICAPABILITIES.setPhoneCallAvilable(GENERAL_BOOLEAN);
@@ -620,7 +730,35 @@ public class Test {
jsonButton.put(ButtonCapabilities.KEY_UP_DOWN_AVAILABLE, GENERAL_BOOLEAN);
jsonButton.put(ButtonCapabilities.KEY_NAME, ButtonName.SEEKRIGHT);
JSON_BUTTONCAPABILITIES.put(jsonButton);
-
+
+ JSONObject jsonRadioControlCapabilities = new JSONObject();
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_MODULE_NAME, GENERAL_STRING);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_STATE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE, GENERAL_BOOLEAN);
+ jsonRadioControlCapabilities.put(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE, GENERAL_BOOLEAN);
+ JSON_RADIOCONTROLCAPABILITIES.put(jsonRadioControlCapabilities);
+
+ JSONObject jsonClimateControlCapabilities = new JSONObject();
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_MODULE_NAME, GENERAL_STRING);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_DEFROST_ZONE, GENERAL_DEFROSTZONE_LIST);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE, GENERAL_BOOLEAN);
+ jsonClimateControlCapabilities.put(ClimateControlCapabilities.KEY_VENTILATION_MODE, GENERAL_VENTILATIONMODE_LIST);
+ JSON_CLIMATECONTROLCAPABILITIES.put(jsonClimateControlCapabilities);
+
jsonButton = new JSONObject();
jsonButton.put(SoftButtonCapabilities.KEY_LONG_PRESS_AVAILABLE, GENERAL_BOOLEAN);
jsonButton.put(SoftButtonCapabilities.KEY_SHORT_PRESS_AVAILABLE, GENERAL_BOOLEAN);
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/Validator.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/Validator.java
index 090dce405..1e99e96a5 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/Validator.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/Validator.java
@@ -13,6 +13,8 @@ import com.smartdevicelink.proxy.rpc.BeltStatus;
import com.smartdevicelink.proxy.rpc.BodyInformation;
import com.smartdevicelink.proxy.rpc.ButtonCapabilities;
import com.smartdevicelink.proxy.rpc.Choice;
+import com.smartdevicelink.proxy.rpc.ClimateControlCapabilities;
+import com.smartdevicelink.proxy.rpc.ClimateControlData;
import com.smartdevicelink.proxy.rpc.ClusterModeStatus;
import com.smartdevicelink.proxy.rpc.Coordinate;
import com.smartdevicelink.proxy.rpc.DIDResult;
@@ -31,11 +33,18 @@ import com.smartdevicelink.proxy.rpc.ImageField;
import com.smartdevicelink.proxy.rpc.ImageResolution;
import com.smartdevicelink.proxy.rpc.KeyboardProperties;
import com.smartdevicelink.proxy.rpc.MenuParams;
+import com.smartdevicelink.proxy.rpc.ModuleData;
import com.smartdevicelink.proxy.rpc.MyKey;
+import com.smartdevicelink.proxy.rpc.NavigationCapability;
import com.smartdevicelink.proxy.rpc.OasisAddress;
import com.smartdevicelink.proxy.rpc.ParameterPermissions;
import com.smartdevicelink.proxy.rpc.PermissionItem;
+import com.smartdevicelink.proxy.rpc.PhoneCapability;
import com.smartdevicelink.proxy.rpc.PresetBankCapabilities;
+import com.smartdevicelink.proxy.rpc.RadioControlCapabilities;
+import com.smartdevicelink.proxy.rpc.RadioControlData;
+import com.smartdevicelink.proxy.rpc.RdsData;
+import com.smartdevicelink.proxy.rpc.RemoteControlCapabilities;
import com.smartdevicelink.proxy.rpc.Rectangle;
import com.smartdevicelink.proxy.rpc.ScreenParams;
import com.smartdevicelink.proxy.rpc.SdlMsgVersion;
@@ -44,6 +53,7 @@ import com.smartdevicelink.proxy.rpc.SoftButton;
import com.smartdevicelink.proxy.rpc.SoftButtonCapabilities;
import com.smartdevicelink.proxy.rpc.StartTime;
import com.smartdevicelink.proxy.rpc.TTSChunk;
+import com.smartdevicelink.proxy.rpc.Temperature;
import com.smartdevicelink.proxy.rpc.TextField;
import com.smartdevicelink.proxy.rpc.TireStatus;
import com.smartdevicelink.proxy.rpc.TouchCoord;
@@ -55,8 +65,10 @@ import com.smartdevicelink.proxy.rpc.VehicleType;
import com.smartdevicelink.proxy.rpc.VideoStreamingCapability;
import com.smartdevicelink.proxy.rpc.VideoStreamingFormat;
import com.smartdevicelink.proxy.rpc.VrHelpItem;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
import com.smartdevicelink.proxy.rpc.enums.FileType;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities;
import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities;
@@ -526,6 +538,342 @@ public class Validator{
return true;
}
+ public static boolean validateTemperature(Temperature temperature1, Temperature temperature2){
+ if(temperature1 == null){
+ return ( temperature2 == null );
+ }
+ if(temperature2 == null){
+ return ( temperature1 == null );
+ }
+
+ if((float) temperature1.getValue() != (float) temperature2.getValue()){
+ log("validateTemperature",
+ "Value " + temperature1.getValue() + " didn't match value " + temperature2.getValue()
+ + ".");
+ return false;
+ }
+
+ if(temperature1.getUnit() != temperature2.getUnit()){
+ log("validateTemperature",
+ "Unit " + temperature1.getUnit() + " didn't match unit " + temperature2.getUnit() + ".");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validateRdsData(RdsData rdsData1, RdsData rdsData2){
+ if(rdsData1 == null){
+ return ( rdsData2 == null );
+ }
+ if(rdsData2 == null){
+ return ( rdsData1 == null );
+ }
+
+ if(rdsData1.getProgramService() != rdsData2.getProgramService()){
+ log("validateRdsData",
+ "Ps " + rdsData1.getProgramService() + " didn't match Ps " + rdsData2.getProgramService()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getRadioText() != rdsData2.getRadioText()){
+ log("validateRdsData",
+ "Rt " + rdsData1.getRadioText() + " didn't match Rt " + rdsData2.getRadioText()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getClockText() != rdsData2.getClockText()){
+ log("validateRdsData",
+ "Ct " + rdsData1.getClockText() + " didn't match Ct " + rdsData2.getClockText()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getProgramIdentification() != rdsData2.getProgramIdentification()){
+ log("validateRdsData",
+ "Pi " + rdsData1.getProgramIdentification() + " didn't match Pi " + rdsData2.getProgramIdentification()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getRegion() != rdsData2.getRegion()){
+ log("validateRdsData",
+ "Reg " + rdsData1.getRegion() + " didn't match Reg " + rdsData2.getRegion()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getTrafficProgram() != rdsData2.getTrafficProgram()){
+ log("validateRdsData",
+ "Tp " + rdsData1.getTrafficProgram() + " didn't match Tp " + rdsData2.getTrafficProgram()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getTrafficAnnouncement() != rdsData2.getTrafficAnnouncement()){
+ log("validateRdsData",
+ "Ta " + rdsData1.getTrafficAnnouncement() + " didn't match Ta " + rdsData2.getTrafficAnnouncement()
+ + ".");
+ return false;
+ }
+
+ if(rdsData1.getProgramType() != rdsData2.getProgramType()){
+ log("validateRdsData",
+ "Pty " + rdsData1.getProgramType() + " didn't match Pty " + rdsData2.getProgramType()
+ + ".");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validateClimateControlData(ClimateControlData climateControlData1, ClimateControlData climateControlData2){
+ if(climateControlData1 == null){
+ return ( climateControlData2 == null );
+ }
+ if(climateControlData2 == null){
+ return ( climateControlData1 == null );
+ }
+
+ if(climateControlData1.getFanSpeed() != climateControlData2.getFanSpeed()){
+ log("validateClimateControlData",
+ "FanSpeed " + climateControlData1.getFanSpeed() + " didn't match fanSpeed " + climateControlData2.getFanSpeed()
+ + ".");
+ return false;
+ }
+
+ if(!( validateTemperature(climateControlData1.getCurrentTemperature(), climateControlData2.getCurrentTemperature()) )){
+ return false;
+ }
+
+ if(!( validateTemperature(climateControlData1.getDesiredTemperature(), climateControlData2.getDesiredTemperature()) )){
+ return false;
+ }
+
+ if(climateControlData1.getAcEnable() != climateControlData2.getAcEnable()){
+ log("validateClimateControlData",
+ "AcEnable " + climateControlData1.getAcEnable() + " didn't match AcEnable " + climateControlData2.getAcEnable()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getCirculateAirEnable() != climateControlData2.getCirculateAirEnable()){
+ log("validateClimateControlData",
+ "CirculateAirEnable " + climateControlData1.getCirculateAirEnable() + " didn't match CirculateAirEnable " + climateControlData2.getCirculateAirEnable()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getAutoModeEnable() != climateControlData2.getAutoModeEnable()){
+ log("validateClimateControlData",
+ "AutoModeEnable " + climateControlData1.getAutoModeEnable() + " didn't match AutoModeEnable " + climateControlData2.getAutoModeEnable()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getDefrostZone() != climateControlData2.getDefrostZone()){
+ log("validateClimateControlData",
+ "DefrostZone " + climateControlData1.getDefrostZone() + " didn't match DefrostZone " + climateControlData2.getDefrostZone()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getDualModeEnable() != climateControlData2.getDualModeEnable()){
+ log("validateClimateControlData",
+ "DualModeEnable " + climateControlData1.getDualModeEnable() + " didn't match DualModeEnable " + climateControlData2.getDualModeEnable()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getAcMaxEnable() != climateControlData2.getAcMaxEnable()){
+ log("validateClimateControlData",
+ "AcMaxEnable " + climateControlData1.getAcMaxEnable() + " didn't match AcMaxEnable " + climateControlData2.getAcMaxEnable()
+ + ".");
+ return false;
+ }
+
+ if(climateControlData1.getVentilationMode() != climateControlData2.getVentilationMode()){
+ log("validateClimateControlData",
+ "VentilationMode " + climateControlData1.getVentilationMode() + " didn't match VentilationMode " + climateControlData2.getVentilationMode()
+ + ".");
+ return false;
+ }
+
+
+ return true;
+ }
+
+ public static boolean validateModuleData(ModuleData moduleData1, ModuleData moduleData2){
+ if(moduleData1 == null){
+ return ( moduleData2 == null );
+ }
+ if(moduleData2 == null){
+ return ( moduleData1 == null );
+ }
+
+ if(moduleData1.getModuleType() != moduleData2.getModuleType()){
+ log("validateModuleData",
+ "ModuleType " + moduleData1.getModuleType() + " didn't match ModuleType " + moduleData2.getModuleType()
+ + ".");
+ return false;
+ }
+
+ if(!( validateRadioControlData(moduleData1.getRadioControlData(), moduleData2.getRadioControlData()) )){
+ return false;
+ }
+
+ if(!( validateClimateControlData(moduleData1.getClimateControlData(), moduleData2.getClimateControlData()) )){
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validateRemoteControlCapabilities(RemoteControlCapabilities remoteControlCapabilities1, RemoteControlCapabilities remoteControlCapabilities2){
+ if(remoteControlCapabilities1 == null){
+ return ( remoteControlCapabilities2 == null );
+ }
+ if(remoteControlCapabilities2 == null){
+ return ( remoteControlCapabilities1 == null );
+ }
+
+ if(!( validateButtonCapabilities(remoteControlCapabilities1.getButtonCapabilities(), remoteControlCapabilities2.getButtonCapabilities()) )){
+ return false;
+ }
+
+ if(!( validateRadioControlCapabilities(remoteControlCapabilities1.getRadioControlCapabilities(), remoteControlCapabilities2.getRadioControlCapabilities()) )){
+ return false;
+ }
+
+ if(!( validateClimateControlCapabilities(remoteControlCapabilities1.getClimateControlCapabilities(), remoteControlCapabilities2.getClimateControlCapabilities()) )){
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validateRadioControlData(RadioControlData radioControlData1, RadioControlData radioControlData2){
+ if(radioControlData1 == null){
+ return ( radioControlData2 == null );
+ }
+ if(radioControlData2 == null){
+ return ( radioControlData1 == null );
+ }
+
+ if(radioControlData1.getFrequencyInteger() != radioControlData2.getFrequencyInteger()){
+ log("validateRadioControlData",
+ "FrequencyInteger " + radioControlData1.getFrequencyInteger() + " didn't match FrequencyInteger " + radioControlData2.getFrequencyInteger()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getFrequencyFraction() != radioControlData2.getFrequencyFraction()){
+ log("validateRadioControlData",
+ "FrequencyFraction " + radioControlData1.getFrequencyFraction() + " didn't match FrequencyFraction " + radioControlData2.getFrequencyFraction()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getBand() != radioControlData2.getBand()){
+ log("validateRadioControlData",
+ "Band " + radioControlData1.getBand() + " didn't match Band " + radioControlData2.getBand()
+ + ".");
+ return false;
+ }
+
+ if(!( validateRdsData(radioControlData1.getRdsData(), radioControlData2.getRdsData()) )){
+ return false;
+ }
+
+ if(radioControlData1.getAvailableHDs() != radioControlData2.getAvailableHDs()){
+ log("validateRadioControlData",
+ "AvailableHDs " + radioControlData1.getAvailableHDs() + " didn't match AvailableHDs " + radioControlData2.getAvailableHDs()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getHdChannel() != radioControlData2.getHdChannel()){
+ log("validateRadioControlData",
+ "HdChannel " + radioControlData1.getHdChannel() + " didn't match HdChannel " + radioControlData2.getHdChannel()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getSignalStrength() != radioControlData2.getSignalStrength()){
+ log("validateRadioControlData",
+ "SignalStrength " + radioControlData1.getSignalStrength() + " didn't match SignalStrength " + radioControlData2.getSignalStrength()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getSignalChangeThreshold() != radioControlData2.getSignalChangeThreshold()){
+ log("validateRadioControlData",
+ "SignalChangeThreshold " + radioControlData1.getSignalChangeThreshold() + " didn't match SignalChangeThreshold " + radioControlData2.getSignalChangeThreshold()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getRadioEnable() != radioControlData2.getRadioEnable()){
+ log("validateRadioControlData",
+ "RadioEnable " + radioControlData1.getRadioEnable() + " didn't match RadioEnable " + radioControlData2.getRadioEnable()
+ + ".");
+ return false;
+ }
+
+ if(radioControlData1.getState() != radioControlData2.getState()){
+ log("validateRadioControlData",
+ "State " + radioControlData1.getState() + " didn't match State " + radioControlData2.getState()
+ + ".");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validateNavigationCapability(NavigationCapability navigationCapability1, NavigationCapability navigationCapability2){
+ if(navigationCapability1 == null){
+ return ( navigationCapability2 == null );
+ }
+ if(navigationCapability2 == null){
+ return ( navigationCapability1 == null );
+ }
+
+ if(navigationCapability1.getSendLocationEnabled() != navigationCapability2.getSendLocationEnabled()){
+ log("validateNavigationCapability",
+ "SendLocationEnabled " + navigationCapability1.getSendLocationEnabled() + " didn't match SendLocationEnabled " + navigationCapability2.getSendLocationEnabled()
+ + ".");
+ return false;
+ }
+
+ if(navigationCapability1.getWayPointsEnabled() != navigationCapability2.getWayPointsEnabled()){
+ log("validateNavigationCapability",
+ "WayPointsEnabled " + navigationCapability1.getWayPointsEnabled() + " didn't match WayPointsEnabled " + navigationCapability2.getWayPointsEnabled() + ".");
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean validatePhoneCapability(PhoneCapability phoneCapability1, PhoneCapability phoneCapability2){
+ if(phoneCapability1 == null){
+ return ( phoneCapability2 == null );
+ }
+ if(phoneCapability2 == null){
+ return ( phoneCapability1 == null );
+ }
+
+ if(phoneCapability1.getDialNumberEnabled() != phoneCapability2.getDialNumberEnabled()){
+ log("validatePhoneCapability",
+ "DialNumberEnabled " + phoneCapability1.getDialNumberEnabled() + " didn't match DialNumberEnabled " + phoneCapability1.getDialNumberEnabled()
+ + ".");
+ return false;
+ }
+
+ return true;
+ }
+
public static boolean validateTouchEventCapabilities(TouchEventCapabilities item1, TouchEventCapabilities item2){
if(item1 == null){
return ( item2 == null );
@@ -1369,7 +1717,154 @@ public class Validator{
return true;
}
-
+
+ public static boolean validateRadioControlCapabilities (List<RadioControlCapabilities> item1, List<RadioControlCapabilities> item2) {
+ if (item1 == null) {
+ return ( item2 == null );
+ }
+ if (item2 == null) {
+ return ( item1 == null );
+ }
+
+ if (item1.size() != item2.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < item1.size(); i++) {
+ if (item1.get(i).getModuleName() != item2.get(i).getModuleName()) {
+ return false;
+ }
+ if (item1.get(i).getRadioEnableAvailable() != item2.get(i).getRadioEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getRadioBandAvailable() != item2.get(i).getRadioBandAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getRadioFrequencyAvailable() != item2.get(i).getRadioFrequencyAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getHdChannelAvailable() != item2.get(i).getHdChannelAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getRdsDataAvailable() != item2.get(i).getRdsDataAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getAvailableHDsAvailable() != item2.get(i).getAvailableHDsAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getStateAvailable() != item2.get(i).getStateAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getSignalStrengthAvailable() != item2.get(i).getSignalStrengthAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getSignalChangeThresholdAvailable() != item2.get(i).getSignalChangeThresholdAvailable()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean validateClimateControlCapabilities (List<ClimateControlCapabilities> item1, List<ClimateControlCapabilities> item2) {
+ if (item1 == null) {
+ return ( item2 == null );
+ }
+ if (item2 == null) {
+ return ( item1 == null );
+ }
+
+ if (item1.size() != item2.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < item1.size(); i++) {
+ if (item1.get(i).getModuleName() != item2.get(i).getModuleName()) {
+ return false;
+ }
+ if (item1.get(i).getFanSpeedAvailable() != item2.get(i).getFanSpeedAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getDesiredTemperatureAvailable() != item2.get(i).getDesiredTemperatureAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getAcEnableAvailable() != item2.get(i).getAcEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getAcMaxEnableAvailable() != item2.get(i).getAcMaxEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getCirculateAirEnableAvailable() != item2.get(i).getCirculateAirEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getAutoModeEnableAvailable() != item2.get(i).getAutoModeEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getDualModeEnableAvailable() != item2.get(i).getDualModeEnableAvailable()) {
+ return false;
+ }
+ if (item1.get(i).getDefrostZoneAvailable() != item2.get(i).getDefrostZoneAvailable()) {
+ return false;
+ }
+
+ if(! (validateDefrostZones(item1.get(i).getDefrostZone(), item2.get(i).getDefrostZone()) )){
+ return false;
+ }
+
+ if (item1.get(i).getVentilationModeAvailable() != item2.get(i).getVentilationModeAvailable()) {
+ return false;
+ }
+
+ if(! (validateVentilationModes(item1.get(i).getVentilationMode(), item2.get(i).getVentilationMode()) )){
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean validateDefrostZones (List<DefrostZone> item1, List<DefrostZone> item2) {
+ if (item1 == null) {
+ return ( item2 == null );
+ }
+ if (item2 == null) {
+ return ( item1 == null );
+ }
+
+ if (item1.size() != item2.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < item1.size(); i++) {
+ if (item1.get(i) != item2.get(i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean validateVentilationModes (List<VentilationMode> item1, List<VentilationMode> item2) {
+ if (item1 == null) {
+ return ( item2 == null );
+ }
+ if (item2 == null) {
+ return ( item1 == null );
+ }
+
+ if (item1.size() != item2.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < item1.size(); i++) {
+ if (item1.get(i) != item2.get(i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public static boolean validateTurnList (List<Turn> item1, List<Turn> item2) {
if (item1 == null) {
return (item2 == null);
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/encoder/EncoderUtilsTest.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/encoder/EncoderUtilsTest.java
new file mode 100644
index 000000000..083a5dd3f
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/encoder/EncoderUtilsTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.encoder;
+
+import android.annotation.TargetApi;
+import android.media.MediaFormat;
+import android.os.Build;
+
+import com.smartdevicelink.encoder.EncoderUtils;
+
+import junit.framework.TestCase;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.encoder.EncoderUtils}
+ */
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public class EncoderUtilsTest extends TestCase {
+ public void testGetCodecSpecificDataWithNull() {
+ byte[] result = EncoderUtils.getCodecSpecificData(null);
+ assertNull(result);
+ }
+
+ public void testGetCodecSpecificDataForAVC() {
+ // example of SPS NAL unit with 4-byte start code
+ byte[] sps = new byte[] {
+ 0x00, 0x00, 0x00, 0x01,
+ 0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60
+ };
+ // example of PPS NAL unit with 4-byte start code
+ byte[] pps = new byte[] {
+ 0x00, 0x00, 0x00, 0x01,
+ 0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20
+ };
+
+ ByteBuffer spsByteBuffer = ByteBuffer.allocate(sps.length);
+ spsByteBuffer.put(sps);
+ spsByteBuffer.flip();
+
+ ByteBuffer ppsByteBuffer = ByteBuffer.allocate(pps.length);
+ ppsByteBuffer.put(pps);
+ ppsByteBuffer.flip();
+
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", 16, 16);
+ format.setByteBuffer("csd-0", spsByteBuffer);
+ format.setByteBuffer("csd-1", ppsByteBuffer);
+
+ byte[] result = EncoderUtils.getCodecSpecificData(format);
+ assertNotNull(result);
+
+ byte[] expected = new byte[sps.length + pps.length];
+ System.arraycopy(sps, 0, expected, 0, sps.length);
+ System.arraycopy(pps, 0, expected, sps.length, pps.length);
+ assertTrue("Output codec specific data doesn't match", Arrays.equals(expected, result));
+ }
+
+ public void testGetCodecSpecificDataWithInvalidAVCData() {
+ // testing an error case when the encoder emits SPS only (which should not happen)
+ byte[] sps = new byte[] {
+ 0x00, 0x00, 0x00, 0x01,
+ 0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60
+ };
+
+ ByteBuffer spsByteBuffer = ByteBuffer.allocate(sps.length);
+ spsByteBuffer.put(sps);
+ spsByteBuffer.flip();
+
+ MediaFormat format = MediaFormat.createVideoFormat("video/avc", 16, 16);
+ format.setByteBuffer("csd-0", spsByteBuffer);
+ // no PPS
+
+ byte[] result = EncoderUtils.getCodecSpecificData(format);
+ assertNull(result);
+ }
+
+ public void testGetCodecSpecificDataForUnknownCodec() {
+ MediaFormat format = MediaFormat.createVideoFormat("video/raw", 16, 16);
+ byte[] result = EncoderUtils.getCodecSpecificData(format);
+ assertNull("For unsupported codec, getCodecSpecificData should return null", result);
+ }
+}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
index ee8d7d0ee..678a4e95b 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SdlProxyBaseTests.java
@@ -17,6 +17,7 @@ import com.smartdevicelink.proxy.rpc.AddCommandResponse;
import com.smartdevicelink.proxy.rpc.AddSubMenuResponse;
import com.smartdevicelink.proxy.rpc.AlertManeuverResponse;
import com.smartdevicelink.proxy.rpc.AlertResponse;
+import com.smartdevicelink.proxy.rpc.ButtonPressResponse;
import com.smartdevicelink.proxy.rpc.ChangeRegistrationResponse;
import com.smartdevicelink.proxy.rpc.CreateInteractionChoiceSetResponse;
import com.smartdevicelink.proxy.rpc.DeleteCommandResponse;
@@ -28,6 +29,7 @@ import com.smartdevicelink.proxy.rpc.DialNumberResponse;
import com.smartdevicelink.proxy.rpc.EndAudioPassThruResponse;
import com.smartdevicelink.proxy.rpc.GenericResponse;
import com.smartdevicelink.proxy.rpc.GetDTCsResponse;
+import com.smartdevicelink.proxy.rpc.GetInteriorVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.GetSystemCapabilityResponse;
import com.smartdevicelink.proxy.rpc.GetVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.GetWayPointsResponse;
@@ -39,6 +41,7 @@ import com.smartdevicelink.proxy.rpc.OnCommand;
import com.smartdevicelink.proxy.rpc.OnDriverDistraction;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.OnHashChange;
+import com.smartdevicelink.proxy.rpc.OnInteriorVehicleData;
import com.smartdevicelink.proxy.rpc.OnKeyboardInput;
import com.smartdevicelink.proxy.rpc.OnLanguageChange;
import com.smartdevicelink.proxy.rpc.OnLockScreenStatus;
@@ -60,6 +63,7 @@ import com.smartdevicelink.proxy.rpc.SendLocationResponse;
import com.smartdevicelink.proxy.rpc.SetAppIconResponse;
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.ShowConstantTbtResponse;
import com.smartdevicelink.proxy.rpc.ShowResponse;
@@ -439,6 +443,26 @@ public class SdlProxyBaseTests extends AndroidTestCase{
}
@Override
+ public void onGetInteriorVehicleDataResponse(GetInteriorVehicleDataResponse response) {
+ Log.i(TAG, "GetInteriorVehicleData response from SDL: " + response);
+ }
+
+ @Override
+ public void onButtonPressResponse(ButtonPressResponse response) {
+ Log.i(TAG, "ButtonPress response from SDL: " + response);
+ }
+
+ @Override
+ public void onSetInteriorVehicleDataResponse(SetInteriorVehicleDataResponse response) {
+ Log.i(TAG, "SetInteriorVehicleData response from SDL: " + response);
+ }
+
+ @Override
+ public void onOnInteriorVehicleData(OnInteriorVehicleData notification) {
+
+ }
+
+ @Override
public void onOnDriverDistraction(OnDriverDistraction notification) {
// Some RPCs (depending on region) cannot be sent when driver distraction is active.
}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
index 89c15ab16..702b83cad 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/proxy/SystemCapabilityManagerTests.java
@@ -2,8 +2,12 @@ package com.smartdevicelink.test.proxy;
import android.test.AndroidTestCase;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.protocol.enums.SessionType;
import com.smartdevicelink.proxy.RPCRequest;
import com.smartdevicelink.proxy.SystemCapabilityManager;
+import com.smartdevicelink.proxy.interfaces.ISdl;
+import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.AudioPassThruCapabilities;
import com.smartdevicelink.proxy.rpc.ButtonCapabilities;
@@ -19,6 +23,8 @@ import com.smartdevicelink.proxy.rpc.VideoStreamingCapability;
import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities;
import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
+import com.smartdevicelink.streaming.VideoStreamingParameters;
import com.smartdevicelink.test.Test;
import com.smartdevicelink.test.Validator;
import com.smartdevicelink.util.CorrelationIdGenerator;
@@ -26,6 +32,8 @@ import com.smartdevicelink.util.CorrelationIdGenerator;
import java.util.List;
import static android.R.id.list;
+import static android.R.id.message;
+import static com.smartdevicelink.proxy.constants.Names.parameters;
public class SystemCapabilityManagerTests extends AndroidTestCase {
public static final String TAG = "SystemCapabilityManagerTests";
@@ -42,12 +50,7 @@ public class SystemCapabilityManagerTests extends AndroidTestCase {
}
public SystemCapabilityManager createSampleManager(){
- SystemCapabilityManager systemCapabilityManager = new SystemCapabilityManager(new SystemCapabilityManager.ISystemCapabilityManager() {
- @Override
- public void onSendPacketRequest(RPCRequest message) {
-
- }
- });
+ SystemCapabilityManager systemCapabilityManager = new SystemCapabilityManager(new InternalSDLInterface());
RegisterAppInterfaceResponse raiResponse = new RegisterAppInterfaceResponse();
@@ -98,9 +101,9 @@ public class SystemCapabilityManagerTests extends AndroidTestCase {
final SystemCapability referenceCapability = cap;
- systemCapabilityManager = new SystemCapabilityManager(new SystemCapabilityManager.ISystemCapabilityManager() {
+ systemCapabilityManager = new SystemCapabilityManager(new InternalSDLInterface() {
@Override
- public void onSendPacketRequest(RPCRequest message) {
+ public void sendRPCRequest(RPCRequest message) {
GetSystemCapabilityResponse response = new GetSystemCapabilityResponse();
response.setSystemCapability(referenceCapability);
response.setSuccess(true);
@@ -131,7 +134,44 @@ public class SystemCapabilityManagerTests extends AndroidTestCase {
List<SoftButtonCapabilities> list = SystemCapabilityManager.convertToList(capability, SoftButtonCapabilities.class);
assertNotNull(list);
+ }
+
+ private class InternalSDLInterface implements ISdl{
+ @Override
+ public void start(){}
+
+ @Override
+ public void stop() {}
+
+ @Override
+ public boolean isConnected() {return false; }
+
+ @Override
+ public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {}
+
+ @Override
+ public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {}
+
+ @Override
+ public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { }
+
+ @Override
+ public void stopVideoService() {}
+
+ @Override
+ public void startAudioService(boolean encrypted) {}
+
+ @Override
+ public void stopAudioService() {}
+
+ @Override
+ public void sendRPCRequest(RPCRequest message) {}
+
+ @Override
+ public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {}
+ @Override
+ public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {return false;}
}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlCapabilitiesTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlCapabilitiesTests.java
new file mode 100644
index 000000000..33f9d2631
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlCapabilitiesTests.java
@@ -0,0 +1,160 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.ClimateControlCapabilities;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.ClimateControlCapabilities}
+ */
+public class ClimateControlCapabilitiesTests extends TestCase{
+
+ private ClimateControlCapabilities msg;
+
+ @Override
+ public void setUp(){
+ msg = new ClimateControlCapabilities();
+
+ msg.setModuleName(Test.GENERAL_STRING);
+ msg.setFanSpeedAvailable(Test.GENERAL_BOOLEAN);
+ msg.setDesiredTemperatureAvailable(Test.GENERAL_BOOLEAN);
+ msg.setAcEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setAcMaxEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setCirculateAirEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setAutoModeEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setDualModeEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setDefrostZoneAvailable(Test.GENERAL_BOOLEAN);
+ msg.setDefrostZone(Test.GENERAL_DEFROSTZONE_LIST);
+ msg.setVentilationModeAvailable(Test.GENERAL_BOOLEAN);
+ msg.setVentilationMode(Test.GENERAL_VENTILATIONMODE_LIST);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ String moduleName = msg.getModuleName();
+ boolean fanSpeedAvailable = msg.getFanSpeedAvailable();
+ boolean desiredTemperatureAvailable = msg.getDesiredTemperatureAvailable();
+ boolean acEnableAvailable = msg.getAcEnableAvailable();
+ boolean acMaxEnableAvailable = msg.getAcMaxEnableAvailable();
+ boolean circulateAirEnableAvailable = msg.getCirculateAirEnableAvailable();
+ boolean autoModeEnableAvailable = msg.getAutoModeEnableAvailable();
+ boolean dualModeEnableAvailable = msg.getDualModeEnableAvailable();
+ boolean defrostZoneAvailable = msg.getDefrostZoneAvailable();
+ List<DefrostZone> defrostZone = msg.getDefrostZone();
+ boolean ventilationModeAvailable = msg.getVentilationModeAvailable();
+ List<VentilationMode> ventilationMode = msg.getVentilationMode();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, moduleName);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, fanSpeedAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, desiredTemperatureAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, acEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, acMaxEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, circulateAirEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, autoModeEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, dualModeEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, defrostZoneAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, ventilationModeAvailable);
+
+ assertEquals(Test.MATCH, Test.GENERAL_DEFROSTZONE_LIST.size(), defrostZone.size());
+ assertEquals(Test.MATCH, Test.GENERAL_VENTILATIONMODE_LIST.size(), ventilationMode.size());
+
+ for(int i = 0; i < Test.GENERAL_DEFROSTZONE_LIST.size(); i++){
+ assertEquals(Test.MATCH, Test.GENERAL_DEFROSTZONE_LIST.get(i), defrostZone.get(i));
+ }
+ for(int i = 0; i < Test.GENERAL_VENTILATIONMODE_LIST.size(); i++){
+ assertEquals(Test.MATCH, Test.GENERAL_VENTILATIONMODE_LIST.get(i), ventilationMode.get(i));
+ }
+
+ // Invalid/Null Tests
+ ClimateControlCapabilities msg = new ClimateControlCapabilities();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getModuleName());
+ assertNull(Test.NULL, msg.getFanSpeedAvailable());
+ assertNull(Test.NULL, msg.getDesiredTemperatureAvailable());
+ assertNull(Test.NULL, msg.getAcEnableAvailable());
+ assertNull(Test.NULL, msg.getAcMaxEnableAvailable());
+ assertNull(Test.NULL, msg.getAutoModeEnableAvailable());
+ assertNull(Test.NULL, msg.getDualModeEnableAvailable());
+ assertNull(Test.NULL, msg.getDefrostZoneAvailable());
+ assertNull(Test.NULL, msg.getDefrostZone());
+ assertNull(Test.NULL, msg.getVentilationModeAvailable());
+ assertNull(Test.NULL, msg.getVentilationMode());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(ClimateControlCapabilities.KEY_MODULE_NAME, Test.GENERAL_STRING);
+ reference.put(ClimateControlCapabilities.KEY_FAN_SPEED_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_DESIRED_TEMPERATURE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_AC_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_AC_MAX_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_CIRCULATE_AIR_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_AUTO_MODE_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_DUAL_MODE_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_DEFROST_ZONE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_VENTILATION_MODE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlCapabilities.KEY_DEFROST_ZONE, JsonUtils.createJsonArray(Test.GENERAL_DEFROSTZONE_LIST));
+ reference.put(ClimateControlCapabilities.KEY_VENTILATION_MODE, JsonUtils.createJsonArray(Test.GENERAL_VENTILATIONMODE_LIST));
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ if(key.equals(ClimateControlCapabilities.KEY_DEFROST_ZONE)) {
+ JSONArray defrostZoneArrayReference = JsonUtils.readJsonArrayFromJsonObject(reference, key);
+ JSONArray defrostZoneArrayTest = JsonUtils.readJsonArrayFromJsonObject(underTest, key);
+ List<DefrostZone> defrostZoneListReference = new ArrayList<DefrostZone>();
+ List<DefrostZone> defrostZoneListTest = new ArrayList<DefrostZone>();
+
+ assertEquals(Test.MATCH, defrostZoneArrayReference.length(), defrostZoneArrayTest.length());
+
+ for (int index = 0 ; index < defrostZoneArrayReference.length(); index++) {
+ defrostZoneListReference.add( (DefrostZone)defrostZoneArrayReference.get(index) );
+ defrostZoneListTest.add( (DefrostZone)defrostZoneArrayTest.get(index) );
+ }
+ assertTrue(Test.TRUE, defrostZoneListReference.containsAll(defrostZoneListTest) && defrostZoneListTest.containsAll(defrostZoneListReference));
+ } else if(key.equals(ClimateControlCapabilities.KEY_VENTILATION_MODE)) {
+ JSONArray ventilationModeArrayReference = JsonUtils.readJsonArrayFromJsonObject(reference, key);
+ JSONArray ventilationModeArrayTest = JsonUtils.readJsonArrayFromJsonObject(underTest, key);
+ List<VentilationMode> ventilationModeListReference = new ArrayList<VentilationMode>();
+ List<VentilationMode> ventilationModeListTest = new ArrayList<VentilationMode>();
+
+ assertEquals(Test.MATCH, ventilationModeArrayReference.length(), ventilationModeArrayTest.length());
+
+ for (int index = 0 ; index < ventilationModeArrayReference.length(); index++) {
+ ventilationModeListReference.add( (VentilationMode)ventilationModeArrayReference.get(index) );
+ ventilationModeListTest.add( (VentilationMode)ventilationModeArrayTest.get(index) );
+ }
+ assertTrue(Test.TRUE, ventilationModeListReference.containsAll(ventilationModeListTest) && ventilationModeListTest.containsAll(ventilationModeListReference));
+ } else{
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlDataTests.java
new file mode 100644
index 000000000..5b0eefa9f
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ClimateControlDataTests.java
@@ -0,0 +1,130 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.proxy.rpc.ClimateControlData;
+import com.smartdevicelink.proxy.rpc.Temperature;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.ClimateControlData}
+ */
+public class ClimateControlDataTests extends TestCase{
+
+ private ClimateControlData msg;
+
+ @Override
+ public void setUp(){
+ msg = new ClimateControlData();
+
+ msg.setFanSpeed(Test.GENERAL_INT);
+ msg.setCurrentTemperature(Test.GENERAL_TEMPERATURE);
+ msg.setDesiredTemperature(Test.GENERAL_TEMPERATURE);
+ msg.setAcEnable(Test.GENERAL_BOOLEAN);
+ msg.setCirculateAirEnable(Test.GENERAL_BOOLEAN);
+ msg.setAutoModeEnable(Test.GENERAL_BOOLEAN);
+ msg.setDefrostZone(Test.GENERAL_DEFROSTZONE);
+ msg.setDualModeEnable(Test.GENERAL_BOOLEAN);
+ msg.setAcMaxEnable(Test.GENERAL_BOOLEAN);
+ msg.setVentilationMode(Test.GENERAL_VENTILATIONMODE);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ int fanSpeed = msg.getFanSpeed();
+ Temperature currentTemperature = msg.getCurrentTemperature();
+ Temperature desiredTemperature = msg.getDesiredTemperature();
+ boolean acEnable = msg.getAcEnable();
+ boolean circulateAirEnable = msg.getCirculateAirEnable();
+ boolean autoModeEnable = msg.getAutoModeEnable();
+ DefrostZone defrostZone = msg.getDefrostZone();
+ boolean dualModeEnable = msg.getDualModeEnable();
+ boolean acMaxEnable = msg.getAcMaxEnable();
+ VentilationMode ventilationMode = msg.getVentilationMode();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_INT, fanSpeed);
+ assertTrue(Test.TRUE, Validator.validateTemperature(Test.GENERAL_TEMPERATURE, currentTemperature));
+ assertTrue(Test.TRUE, Validator.validateTemperature(Test.GENERAL_TEMPERATURE, desiredTemperature));
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, acEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, circulateAirEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, autoModeEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_DEFROSTZONE, defrostZone);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, dualModeEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, acMaxEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_VENTILATIONMODE, ventilationMode);
+
+ // Invalid/Null Tests
+ ClimateControlData msg = new ClimateControlData();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getFanSpeed());
+ assertNull(Test.NULL, msg.getCurrentTemperature());
+ assertNull(Test.NULL, msg.getDesiredTemperature());
+ assertNull(Test.NULL, msg.getAcEnable());
+ assertNull(Test.NULL, msg.getCirculateAirEnable());
+ assertNull(Test.NULL, msg.getAutoModeEnable());
+ assertNull(Test.NULL, msg.getDefrostZone());
+ assertNull(Test.NULL, msg.getDualModeEnable());
+ assertNull(Test.NULL, msg.getAcMaxEnable());
+ assertNull(Test.NULL, msg.getVentilationMode());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(ClimateControlData.KEY_FAN_SPEED, Test.GENERAL_INT);
+ reference.put(ClimateControlData.KEY_CURRENT_TEMPERATURE, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_TEMPERATURE.getStore()));
+ reference.put(ClimateControlData.KEY_DESIRED_TEMPERATURE, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_TEMPERATURE.getStore()));
+ reference.put(ClimateControlData.KEY_AC_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlData.KEY_CIRCULATE_AIR_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlData.KEY_AUTO_MODE_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlData.KEY_DUAL_MODE_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlData.KEY_AC_MAX_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(ClimateControlData.KEY_DEFROST_ZONE, Test.GENERAL_DEFROSTZONE);
+ reference.put(ClimateControlData.KEY_VENTILATION_MODE, Test.GENERAL_VENTILATIONMODE);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ if(key.equals(ClimateControlData.KEY_CURRENT_TEMPERATURE)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateTemperature( new Temperature(hashReference), new Temperature(hashTest)));
+ } else if(key.equals(ClimateControlData.KEY_DESIRED_TEMPERATURE)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateTemperature( new Temperature(hashReference), new Temperature(hashTest)));
+ } else{
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ModuleDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ModuleDataTests.java
new file mode 100644
index 000000000..ea71dfc8a
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/ModuleDataTests.java
@@ -0,0 +1,95 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.proxy.rpc.ClimateControlData;
+import com.smartdevicelink.proxy.rpc.ModuleData;
+import com.smartdevicelink.proxy.rpc.RadioControlData;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.ModuleData}
+ */
+public class ModuleDataTests extends TestCase{
+
+ private ModuleData msg;
+
+ @Override
+ public void setUp(){
+ msg = new ModuleData();
+
+ msg.setModuleType(Test.GENERAL_MODULETYPE);
+ msg.setRadioControlData(Test.GENERAL_RADIOCONTROLDATA);
+ msg.setClimateControlData(Test.GENERAL_CLIMATECONTROLDATA);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleType moduleType = msg.getModuleType();
+ RadioControlData radioControlData = msg.getRadioControlData();
+ ClimateControlData climateControlData = msg.getClimateControlData();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_MODULETYPE, moduleType);
+ assertTrue(Test.TRUE, Validator.validateRadioControlData(Test.GENERAL_RADIOCONTROLDATA, radioControlData));
+ assertTrue(Test.TRUE, Validator.validateClimateControlData(Test.GENERAL_CLIMATECONTROLDATA, climateControlData));
+
+ // Invalid/Null Tests
+ ModuleData msg = new ModuleData();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getModuleType());
+ assertNull(Test.NULL, msg.getRadioControlData());
+ assertNull(Test.NULL, msg.getClimateControlData());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(ModuleData.KEY_MODULE_TYPE, Test.GENERAL_MODULETYPE);
+ reference.put(ModuleData.KEY_RADIO_CONTROL_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_RADIOCONTROLDATA.getStore()));
+ reference.put(ModuleData.KEY_CLIMATE_CONTROL_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_CLIMATECONTROLDATA.getStore()));
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ if(key.equals(ModuleData.KEY_RADIO_CONTROL_DATA)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateRadioControlData( new RadioControlData(hashReference), new RadioControlData(hashTest)));
+ } else if(key.equals(ModuleData.KEY_CLIMATE_CONTROL_DATA)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateClimateControlData( new ClimateControlData(hashReference), new ClimateControlData(hashTest)));
+ } else{
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/NavigationCapabilityTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/NavigationCapabilityTests.java
new file mode 100644
index 000000000..efbf7e30d
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/NavigationCapabilityTests.java
@@ -0,0 +1,69 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.NavigationCapability;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.NavigationCapability}
+ */
+public class NavigationCapabilityTests extends TestCase{
+
+ private NavigationCapability msg;
+
+ @Override
+ public void setUp(){
+ msg = new NavigationCapability();
+
+ msg.setSendLocationEnabled(Test.GENERAL_BOOLEAN);
+ msg.setWayPointsEnabled(Test.GENERAL_BOOLEAN);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ boolean sendLocationEnabled = msg.getSendLocationEnabled();
+ boolean getWayPointsEnabled = msg.getWayPointsEnabled();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, sendLocationEnabled);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, getWayPointsEnabled);
+
+ // Invalid/Null Tests
+ NavigationCapability msg = new NavigationCapability();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getSendLocationEnabled());
+ assertNull(Test.NULL, msg.getWayPointsEnabled());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(NavigationCapability.KEY_GETWAYPOINTS_ENABLED, Test.GENERAL_BOOLEAN);
+ reference.put(NavigationCapability.KEY_LOCATION_ENABLED, Test.GENERAL_BOOLEAN);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/PhoneCapabilityTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/PhoneCapabilityTests.java
new file mode 100644
index 000000000..2614db0fd
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/PhoneCapabilityTests.java
@@ -0,0 +1,64 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.PhoneCapability;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.PhoneCapability}
+ */
+public class PhoneCapabilityTests extends TestCase{
+
+ private PhoneCapability msg;
+
+ @Override
+ public void setUp(){
+ msg = new PhoneCapability();
+
+ msg.setDialNumberEnabled(Test.GENERAL_BOOLEAN);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ boolean dialNumberEnabled = msg.getDialNumberEnabled();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, dialNumberEnabled);
+
+ // Invalid/Null Tests
+ PhoneCapability msg = new PhoneCapability();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getDialNumberEnabled());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(PhoneCapability.KEY_DIALNUMBER_ENABLED, Test.GENERAL_BOOLEAN);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlCapabilitiesTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlCapabilitiesTests.java
new file mode 100644
index 000000000..28c1d2c5b
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlCapabilitiesTests.java
@@ -0,0 +1,112 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.RadioControlCapabilities;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.RadioControlCapabilities}
+ */
+public class RadioControlCapabilitiesTests extends TestCase{
+
+ private RadioControlCapabilities msg;
+
+ @Override
+ public void setUp(){
+ msg = new RadioControlCapabilities();
+
+ msg.setModuleName(Test.GENERAL_STRING);
+ msg.setRadioEnableAvailable(Test.GENERAL_BOOLEAN);
+ msg.setRadioBandAvailable(Test.GENERAL_BOOLEAN);
+ msg.setRadioFrequencyAvailable(Test.GENERAL_BOOLEAN);
+ msg.setHdChannelAvailable(Test.GENERAL_BOOLEAN);
+ msg.setRdsDataAvailable(Test.GENERAL_BOOLEAN);
+ msg.setAvailableHDsAvailable(Test.GENERAL_BOOLEAN);
+ msg.setStateAvailable(Test.GENERAL_BOOLEAN);
+ msg.setSignalStrengthAvailable(Test.GENERAL_BOOLEAN);
+ msg.setSignalChangeThresholdAvailable(Test.GENERAL_BOOLEAN);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ String moduleName = msg.getModuleName();
+ boolean radioEnableAvailable = msg.getRadioEnableAvailable();
+ boolean radioBandAvailable = msg.getRadioBandAvailable();
+ boolean radioFrequencyAvailable = msg.getRadioFrequencyAvailable();
+ boolean hdChannelAvailable = msg.getHdChannelAvailable();
+ boolean rdsDataAvailable = msg.getRdsDataAvailable();
+ boolean availableHDsAvailable = msg.getAvailableHDsAvailable();
+ boolean stateAvailable = msg.getStateAvailable();
+ boolean signalStrengthAvailable = msg.getSignalStrengthAvailable();
+ boolean signalChangeThresholdAvailable = msg.getSignalChangeThresholdAvailable();
+
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, moduleName);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, radioEnableAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, radioBandAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, radioFrequencyAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, hdChannelAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, rdsDataAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, availableHDsAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, stateAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, signalStrengthAvailable);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, signalChangeThresholdAvailable);
+
+ // Invalid/Null Tests
+ RadioControlCapabilities msg = new RadioControlCapabilities();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getModuleName());
+ assertNull(Test.NULL, msg.getRadioEnableAvailable());
+ assertNull(Test.NULL, msg.getRadioBandAvailable());
+ assertNull(Test.NULL, msg.getRadioFrequencyAvailable());
+ assertNull(Test.NULL, msg.getHdChannelAvailable());
+ assertNull(Test.NULL, msg.getRdsDataAvailable());
+ assertNull(Test.NULL, msg.getAvailableHDsAvailable());
+ assertNull(Test.NULL, msg.getStateAvailable());
+ assertNull(Test.NULL, msg.getSignalStrengthAvailable());
+ assertNull(Test.NULL, msg.getSignalChangeThresholdAvailable());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(RadioControlCapabilities.KEY_MODULE_NAME, Test.GENERAL_STRING);
+ reference.put(RadioControlCapabilities.KEY_RADIO_ENABLE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_RADIO_BAND_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_RADIO_FREQUENCY_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_HD_CHANNEL_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_RDS_DATA_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_AVAILABLE_HDS_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_STATE_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_SIGNAL_STRENGTH_AVAILABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlCapabilities.KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE, Test.GENERAL_BOOLEAN);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlDataTests.java
new file mode 100644
index 000000000..b42145e8f
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RadioControlDataTests.java
@@ -0,0 +1,124 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.proxy.rpc.RadioControlData;
+import com.smartdevicelink.proxy.rpc.RdsData;
+import com.smartdevicelink.proxy.rpc.enums.RadioBand;
+import com.smartdevicelink.proxy.rpc.enums.RadioState;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.RadioControlData}
+ */
+public class RadioControlDataTests extends TestCase{
+
+ private RadioControlData msg;
+
+ @Override
+ public void setUp(){
+ msg = new RadioControlData();
+
+ msg.setFrequencyInteger(Test.GENERAL_INT);
+ msg.setFrequencyFraction(Test.GENERAL_INT);
+ msg.setBand(Test.GENERAL_RADIOBAND);
+ msg.setRdsData(Test.GENERAL_RDSDATA);
+ msg.setAvailableHDs(Test.GENERAL_INT);
+ msg.setHdChannel(Test.GENERAL_INT);
+ msg.setSignalStrength(Test.GENERAL_INT);
+ msg.setSignalChangeThreshold(Test.GENERAL_INT);
+ msg.setRadioEnable(Test.GENERAL_BOOLEAN);
+ msg.setState(Test.GENERAL_RADIOSTATE);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ int frequencyInteger = msg.getFrequencyInteger();
+ int frequencyFraction = msg.getFrequencyFraction();
+ RadioBand band = msg.getBand();
+ RdsData rdsData = msg.getRdsData();
+ int availableHDs = msg.getAvailableHDs();
+ int hdChannel = msg.getHdChannel();
+ int signalStrength = msg.getSignalStrength();
+ int signalChangeThreshold = msg.getSignalChangeThreshold();
+ boolean radioEnable = msg.getRadioEnable();
+ RadioState state = msg.getState();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_INT, frequencyInteger);
+ assertEquals(Test.MATCH, Test.GENERAL_INT, frequencyFraction);
+ assertEquals(Test.MATCH, Test.GENERAL_RADIOBAND, band);
+ assertTrue(Test.TRUE, Validator.validateRdsData(Test.GENERAL_RDSDATA, rdsData));
+ assertEquals(Test.MATCH, Test.GENERAL_INT, availableHDs);
+ assertEquals(Test.MATCH, Test.GENERAL_INT, hdChannel);
+ assertEquals(Test.MATCH, Test.GENERAL_INT, signalStrength);
+ assertEquals(Test.MATCH, Test.GENERAL_INT, signalChangeThreshold);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, radioEnable);
+ assertEquals(Test.MATCH, Test.GENERAL_RADIOSTATE, state);
+
+ // Invalid/Null Tests
+ RadioControlData msg = new RadioControlData();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getFrequencyInteger());
+ assertNull(Test.NULL, msg.getFrequencyFraction());
+ assertNull(Test.NULL, msg.getBand());
+ assertNull(Test.NULL, msg.getRdsData());
+ assertNull(Test.NULL, msg.getAvailableHDs());
+ assertNull(Test.NULL, msg.getHdChannel());
+ assertNull(Test.NULL, msg.getSignalStrength());
+ assertNull(Test.NULL, msg.getSignalChangeThreshold());
+ assertNull(Test.NULL, msg.getRadioEnable());
+ assertNull(Test.NULL, msg.getState());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(RadioControlData.KEY_FREQUENCY_INTEGER, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_FREQUENCY_FRACTION, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_BAND, Test.GENERAL_RADIOBAND);
+ reference.put(RadioControlData.KEY_RDS_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_RDSDATA.getStore()));
+ reference.put(RadioControlData.KEY_AVAILABLE_HDS, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_HD_CHANNEL, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_SIGNAL_STRENGTH, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_SIGNAL_CHANGE_THRESHOLD, Test.GENERAL_INT);
+ reference.put(RadioControlData.KEY_RADIO_ENABLE, Test.GENERAL_BOOLEAN);
+ reference.put(RadioControlData.KEY_STATE, Test.GENERAL_RADIOSTATE);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ if(key.equals(RadioControlData.KEY_RDS_DATA)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateRadioControlData( new RadioControlData(hashReference), new RadioControlData(hashTest)));
+ } else{
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RdsDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RdsDataTests.java
new file mode 100644
index 000000000..7414304b0
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RdsDataTests.java
@@ -0,0 +1,101 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.RdsData;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.RdsData}
+ */
+public class RdsDataTests extends TestCase{
+
+ private RdsData msg;
+
+ @Override
+ public void setUp(){
+ msg = new RdsData();
+
+ msg.setProgramService(Test.GENERAL_STRING);
+ msg.setRadioText(Test.GENERAL_STRING);
+ msg.setClockText(Test.GENERAL_STRING);
+ msg.setProgramIdentification(Test.GENERAL_STRING);
+ msg.setRegion(Test.GENERAL_STRING);
+ msg.setTrafficProgram(Test.GENERAL_BOOLEAN);
+ msg.setTrafficAnnouncement(Test.GENERAL_BOOLEAN);
+ msg.setProgramType(Test.GENERAL_INT);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ String ps = msg.getProgramService();
+ String rt = msg.getRadioText();
+ String ct = msg.getClockText();
+ String pi = msg.getProgramIdentification();
+ int pty = msg.getProgramType();
+ boolean tp = msg.getTrafficProgram();
+ boolean ta = msg.getTrafficAnnouncement();
+ String reg = msg.getRegion();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, ps);
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, rt);
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, ct);
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, pi);
+ assertEquals(Test.MATCH, Test.GENERAL_INT, pty);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, tp);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, ta);
+ assertEquals(Test.MATCH, Test.GENERAL_STRING, reg);
+
+ // Invalid/Null Tests
+ RdsData msg = new RdsData();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getProgramService());
+ assertNull(Test.NULL, msg.getRadioText());
+ assertNull(Test.NULL, msg.getClockText());
+ assertNull(Test.NULL, msg.getProgramIdentification());
+ assertNull(Test.NULL, msg.getRegion());
+ assertNull(Test.NULL, msg.getTrafficProgram());
+ assertNull(Test.NULL, msg.getTrafficAnnouncement());
+ assertNull(Test.NULL, msg.getProgramType());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(RdsData.KEY_PS, Test.GENERAL_STRING);
+ reference.put(RdsData.KEY_RT, Test.GENERAL_STRING);
+ reference.put(RdsData.KEY_CT, Test.GENERAL_STRING);
+ reference.put(RdsData.KEY_PI, Test.GENERAL_STRING);
+ reference.put(RdsData.KEY_PTY, Test.GENERAL_INT);
+ reference.put(RdsData.KEY_TP, Test.GENERAL_BOOLEAN);
+ reference.put(RdsData.KEY_TA, Test.GENERAL_BOOLEAN);
+ reference.put(RdsData.KEY_REG, Test.GENERAL_STRING);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RemoteControlCapabilitiesTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RemoteControlCapabilitiesTests.java
new file mode 100644
index 000000000..a15179b8f
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/RemoteControlCapabilitiesTests.java
@@ -0,0 +1,131 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.proxy.rpc.ButtonCapabilities;
+import com.smartdevicelink.proxy.rpc.ClimateControlCapabilities;
+import com.smartdevicelink.proxy.rpc.RadioControlCapabilities;
+import com.smartdevicelink.proxy.rpc.RemoteControlCapabilities;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+
+import junit.framework.TestCase;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.RemoteControlCapabilities}
+ */
+public class RemoteControlCapabilitiesTests extends TestCase{
+
+ private RemoteControlCapabilities msg;
+
+ @Override
+ public void setUp(){
+ msg = new RemoteControlCapabilities();
+
+ msg.setButtonCapabilities(Test.GENERAL_BUTTONCAPABILITIES_LIST);
+ msg.setRadioControlCapabilities(Test.GENERAL_RADIOCONTROLCAPABILITIES_LIST);
+ msg.setClimateControlCapabilities(Test.GENERAL_CLIMATECONTROLCAPABILITIES_LIST);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ List<ButtonCapabilities> buttonCapabilities = msg.getButtonCapabilities();
+ List<RadioControlCapabilities> radioControlCapabilities = msg.getRadioControlCapabilities();
+ List<ClimateControlCapabilities> climateControlCapabilities = msg.getClimateControlCapabilities();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_BUTTONCAPABILITIES_LIST.size(), buttonCapabilities.size());
+ assertEquals(Test.MATCH, Test.GENERAL_RADIOCONTROLCAPABILITIES_LIST.size(), radioControlCapabilities.size());
+ assertEquals(Test.MATCH, Test.GENERAL_CLIMATECONTROLCAPABILITIES_LIST.size(), climateControlCapabilities.size());
+
+ assertTrue(Test.TRUE, Validator.validateButtonCapabilities(Test.GENERAL_BUTTONCAPABILITIES_LIST, buttonCapabilities));
+ assertTrue(Test.TRUE, Validator.validateRadioControlCapabilities(Test.GENERAL_RADIOCONTROLCAPABILITIES_LIST, radioControlCapabilities));
+ assertTrue(Test.TRUE, Validator.validateClimateControlCapabilities(Test.GENERAL_CLIMATECONTROLCAPABILITIES_LIST, climateControlCapabilities));
+
+ // Invalid/Null Tests
+ RemoteControlCapabilities msg = new RemoteControlCapabilities();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getButtonCapabilities());
+ assertNull(Test.NULL, msg.getRadioControlCapabilities());
+ assertNull(Test.NULL, msg.getClimateControlCapabilities());
+
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES, Test.JSON_BUTTONCAPABILITIES);
+ reference.put(RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES, Test.JSON_RADIOCONTROLCAPABILITIES);
+ reference.put(RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES, Test.JSON_CLIMATECONTROLCAPABILITIES);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ if(key.equals(RemoteControlCapabilities.KEY_BUTTON_CAPABILITIES)){
+ JSONArray referenceArray = JsonUtils.readJsonArrayFromJsonObject(reference, key);
+ JSONArray underTestArray = JsonUtils.readJsonArrayFromJsonObject(underTest, key);
+ assertEquals(Test.MATCH, referenceArray.length(), underTestArray.length());
+
+ List<ButtonCapabilities> referenceList = new ArrayList<ButtonCapabilities>();
+ List<ButtonCapabilities> testList = new ArrayList<ButtonCapabilities>();
+ for(int i = 0; i < referenceArray.length(); i++){
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(referenceArray.getJSONObject(i));
+ referenceList.add(new ButtonCapabilities(hashReference));
+ Hashtable<String, Object> hashTest= JsonRPCMarshaller.deserializeJSONObject(underTestArray.getJSONObject(i));
+ testList.add(new ButtonCapabilities(hashTest));
+ }
+ assertTrue(Test.TRUE, Validator.validateButtonCapabilities(referenceList, testList));
+ } else if(key.equals(RemoteControlCapabilities.KEY_RADIO_CONTROL_CAPABILITIES)){
+ JSONArray referenceArray = JsonUtils.readJsonArrayFromJsonObject(reference, key);
+ JSONArray underTestArray = JsonUtils.readJsonArrayFromJsonObject(underTest, key);
+ assertEquals(Test.MATCH, referenceArray.length(), underTestArray.length());
+
+ List<RadioControlCapabilities> referenceList = new ArrayList<RadioControlCapabilities>();
+ List<RadioControlCapabilities> testList = new ArrayList<RadioControlCapabilities>();
+ for(int i = 0; i < referenceArray.length(); i++){
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(referenceArray.getJSONObject(i));
+ referenceList.add(new RadioControlCapabilities(hashReference));
+ Hashtable<String, Object> hashTest= JsonRPCMarshaller.deserializeJSONObject(underTestArray.getJSONObject(i));
+ testList.add(new RadioControlCapabilities(hashTest));
+ }
+ assertTrue(Test.TRUE, Validator.validateRadioControlCapabilities(referenceList, testList));
+ } else if(key.equals(RemoteControlCapabilities.KEY_CLIMATE_CONTROL_CAPABILITIES)){
+ JSONArray referenceArray = JsonUtils.readJsonArrayFromJsonObject(reference, key);
+ JSONArray underTestArray = JsonUtils.readJsonArrayFromJsonObject(underTest, key);
+ assertEquals(Test.MATCH, referenceArray.length(), underTestArray.length());
+
+ List<ClimateControlCapabilities> referenceList = new ArrayList<ClimateControlCapabilities>();
+ List<ClimateControlCapabilities> testList = new ArrayList<ClimateControlCapabilities>();
+ for(int i = 0; i < referenceArray.length(); i++){
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(referenceArray.getJSONObject(i));
+ referenceList.add(new ClimateControlCapabilities(hashReference));
+ Hashtable<String, Object> hashTest= JsonRPCMarshaller.deserializeJSONObject(underTestArray.getJSONObject(i));
+ testList.add(new ClimateControlCapabilities(hashTest));
+ }
+ assertTrue(Test.TRUE, Validator.validateClimateControlCapabilities(referenceList, testList));
+ }
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/SystemCapabilityTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/SystemCapabilityTests.java
index 566b2733e..aa0d75c07 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/SystemCapabilityTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/SystemCapabilityTests.java
@@ -1,17 +1,27 @@
package com.smartdevicelink.test.rpc.datatypes;
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.proxy.rpc.NavigationCapability;
+import com.smartdevicelink.proxy.rpc.PhoneCapability;
+import com.smartdevicelink.proxy.rpc.RemoteControlCapabilities;
import com.smartdevicelink.proxy.rpc.SystemCapability;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.test.JsonUtils;
import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
import junit.framework.TestCase;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.Hashtable;
import java.util.Iterator;
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.SystemCapability}
+ */
public class SystemCapabilityTests extends TestCase {
private SystemCapability msg;
@@ -21,6 +31,10 @@ public class SystemCapabilityTests extends TestCase {
msg = new SystemCapability();
msg.setSystemCapabilityType(Test.GENERAL_SYSTEMCAPABILITYTYPE);
+ msg.setCapabilityForType(SystemCapabilityType.NAVIGATION, Test.GENERAL_NAVIGATIONCAPABILITY);
+ msg.setCapabilityForType(SystemCapabilityType.PHONE_CALL, Test.GENERAL_PHONECAPABILITY);
+ msg.setCapabilityForType(SystemCapabilityType.REMOTE_CONTROL, Test.GENERAL_REMOTECONTROLCAPABILITIES);
+
}
/**
@@ -29,15 +43,24 @@ public class SystemCapabilityTests extends TestCase {
public void testRpcValues () {
// Test Values
SystemCapabilityType testType = msg.getSystemCapabilityType();
+ NavigationCapability testNavigationCapability = (NavigationCapability) msg.getCapabilityForType(SystemCapabilityType.NAVIGATION);
+ PhoneCapability testPhoneCapability = (PhoneCapability) msg.getCapabilityForType(SystemCapabilityType.PHONE_CALL);
+ RemoteControlCapabilities testRemoteControlCapabilities = (RemoteControlCapabilities) msg.getCapabilityForType(SystemCapabilityType.REMOTE_CONTROL);
// Valid Tests
- assertEquals(Test.MATCH, (SystemCapabilityType) Test.GENERAL_SYSTEMCAPABILITYTYPE, testType);
+ assertEquals(Test.MATCH, Test.GENERAL_SYSTEMCAPABILITYTYPE, testType);
+ assertTrue(Test.TRUE, Validator.validateNavigationCapability(Test.GENERAL_NAVIGATIONCAPABILITY, testNavigationCapability));
+ assertTrue(Test.TRUE, Validator.validatePhoneCapability(Test.GENERAL_PHONECAPABILITY, testPhoneCapability));
+ assertTrue(Test.TRUE, Validator.validateRemoteControlCapabilities(Test.GENERAL_REMOTECONTROLCAPABILITIES, testRemoteControlCapabilities));
// Invalid/Null Tests
SystemCapability msg = new SystemCapability();
assertNotNull(Test.NOT_NULL, msg);
assertNull(Test.NULL, msg.getSystemCapabilityType());
+ assertNull(Test.NULL, msg.getCapabilityForType(SystemCapabilityType.NAVIGATION));
+ assertNull(Test.NULL, msg.getCapabilityForType(SystemCapabilityType.PHONE_CALL));
+ assertNull(Test.NULL, msg.getCapabilityForType(SystemCapabilityType.REMOTE_CONTROL));
}
public void testJson() {
@@ -45,6 +68,9 @@ public class SystemCapabilityTests extends TestCase {
try {
reference.put(SystemCapability.KEY_SYSTEM_CAPABILITY_TYPE, Test.GENERAL_SYSTEMCAPABILITYTYPE);
+ reference.put(SystemCapability.KEY_NAVIGATION_CAPABILITY, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_NAVIGATIONCAPABILITY.getStore()));
+ reference.put(SystemCapability.KEY_PHONE_CAPABILITY, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_PHONECAPABILITY.getStore()));
+ reference.put(SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_REMOTECONTROLCAPABILITIES.getStore()));
JSONObject underTest = msg.serializeJSON();
assertEquals(Test.MATCH, reference.length(), underTest.length());
@@ -52,7 +78,28 @@ public class SystemCapabilityTests extends TestCase {
Iterator<?> iterator = reference.keys();
while (iterator.hasNext()) {
String key = (String) iterator.next();
- assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+
+ if(key.equals(SystemCapability.KEY_NAVIGATION_CAPABILITY)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateNavigationCapability( new NavigationCapability(hashReference), new NavigationCapability(hashTest)));
+ } else if(key.equals(SystemCapability.KEY_PHONE_CAPABILITY)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validatePhoneCapability( new PhoneCapability(hashReference), new PhoneCapability(hashTest)));
+ } else if(key.equals(SystemCapability.KEY_REMOTE_CONTROL_CAPABILITY)){
+ JSONObject objectEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(reference, key);
+ JSONObject testEquals = (JSONObject) JsonUtils.readObjectFromJsonObject(underTest, key);
+ Hashtable<String, Object> hashReference = JsonRPCMarshaller.deserializeJSONObject(objectEquals);
+ Hashtable<String, Object> hashTest = JsonRPCMarshaller.deserializeJSONObject(testEquals);
+ assertTrue(Test.TRUE, Validator.validateRemoteControlCapabilities( new RemoteControlCapabilities(hashReference), new RemoteControlCapabilities(hashTest)));
+ } else{
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+ }
}
} catch (JSONException e) {
fail(Test.JSON_FAIL);
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/TemperatureTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/TemperatureTests.java
new file mode 100644
index 000000000..090f5a235
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/datatypes/TemperatureTests.java
@@ -0,0 +1,72 @@
+package com.smartdevicelink.test.rpc.datatypes;
+
+import com.smartdevicelink.proxy.rpc.Temperature;
+import com.smartdevicelink.proxy.rpc.enums.TemperatureUnit;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.Temperature}
+ */
+public class TemperatureTests extends TestCase{
+
+ private Temperature msg;
+
+ @Override
+ public void setUp(){
+ msg = new Temperature();
+
+ msg.setUnit(Test.GENERAL_TEMPERATUREUNIT);
+ msg.setValue(Test.GENERAL_FLOAT);
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ TemperatureUnit unit = msg.getUnit();
+ float value = msg.getValue();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_FLOAT, value);
+ assertEquals(Test.MATCH, Test.GENERAL_TEMPERATUREUNIT, unit);
+
+ // Invalid/Null Tests
+ Temperature msg = new Temperature();
+ assertNotNull(Test.NOT_NULL, msg);
+
+ assertNull(Test.NULL, msg.getUnit());
+ assertNull(Test.NULL, msg.getValue());
+ }
+
+ public void testJson(){
+ JSONObject reference = new JSONObject();
+
+ try{
+ reference.put(Temperature.KEY_VALUE, (Float) Test.GENERAL_FLOAT);
+ reference.put(Temperature.KEY_UNIT, Test.GENERAL_TEMPERATUREUNIT);
+
+ JSONObject underTest = msg.serializeJSON();
+ assertEquals(Test.MATCH, reference.length(), underTest.length());
+
+ Iterator<?> iterator = reference.keys();
+ while(iterator.hasNext()){
+ String key = (String) iterator.next();
+
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(reference, key), JsonUtils.readObjectFromJsonObject(underTest, key));
+
+ }
+ } catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppHmiTypeTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppHmiTypeTests.java
index bcaeae93d..6446cb914 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppHmiTypeTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/AppHmiTypeTests.java
@@ -40,6 +40,8 @@ public class AppHmiTypeTests extends TestCase {
AppHMIType enumTesting = AppHMIType.valueForString(example);
example = "SYSTEM";
AppHMIType enumSystem = AppHMIType.valueForString(example);
+ example = "REMOTE_CONTROL";
+ AppHMIType enumRemoteControl = AppHMIType.valueForString(example);
assertNotNull("DEFAULT returned null", enumDefault);
assertNotNull("COMMUNICATION returned null", enumCommunication);
@@ -52,6 +54,7 @@ public class AppHmiTypeTests extends TestCase {
assertNotNull("PROJECTION returned null", enumProjection);
assertNotNull("TESTING returned null", enumTesting);
assertNotNull("SYSTEM returned null", enumSystem);
+ assertNotNull("REMOTE_CONTROL returned null", enumRemoteControl);
}
/**
@@ -99,7 +102,8 @@ public class AppHmiTypeTests extends TestCase {
enumTestList.add(AppHMIType.BACKGROUND_PROCESS);
enumTestList.add(AppHMIType.PROJECTION);
enumTestList.add(AppHMIType.TESTING);
- enumTestList.add(AppHMIType.SYSTEM);
+ enumTestList.add(AppHMIType.SYSTEM);
+ enumTestList.add(AppHMIType.REMOTE_CONTROL);
assertTrue("Enum value list does not match enum class list",
enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ButtonNameTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ButtonNameTests.java
index 1db7c4580..e37eb2fd1 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ButtonNameTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ButtonNameTests.java
@@ -52,7 +52,44 @@ public class ButtonNameTests extends TestCase {
ButtonName enumCustomButton = ButtonName.valueForString(example);
example = "SEARCH";
ButtonName enumSearch = ButtonName.valueForString(example);
-
+ example = "AC_MAX";
+ ButtonName enumAcMax = ButtonName.valueForString(example);
+ example = "AC";
+ ButtonName enumAc = ButtonName.valueForString(example);
+ example = "RECIRCULATE";
+ ButtonName enumRecirculate = ButtonName.valueForString(example);
+ example = "FAN_UP";
+ ButtonName enumFanUp = ButtonName.valueForString(example);
+ example = "FAN_DOWN";
+ ButtonName enumFanDown = ButtonName.valueForString(example);
+ example = "TEMP_UP";
+ ButtonName enumTempUp = ButtonName.valueForString(example);
+ example = "TEMP_DOWN";
+ ButtonName enumTempDown = ButtonName.valueForString(example);
+ example = "DEFROST_MAX";
+ ButtonName enumDefrostMax = ButtonName.valueForString(example);
+ example = "DEFROST";
+ ButtonName enumDefrost = ButtonName.valueForString(example);
+ example = "DEFROST_REAR";
+ ButtonName enumDefrostRear = ButtonName.valueForString(example);
+ example = "UPPER_VENT";
+ ButtonName enumUpperVent = ButtonName.valueForString(example);
+ example = "LOWER_VENT";
+ ButtonName enumLowerVent = ButtonName.valueForString(example);
+ example = "VOLUME_UP";
+ ButtonName enumVolumeUp = ButtonName.valueForString(example);
+ example = "VOLUME_DOWN";
+ ButtonName enumVolumeDown = ButtonName.valueForString(example);
+ example = "EJECT";
+ ButtonName enumEject = ButtonName.valueForString(example);
+ example = "SOURCE";
+ ButtonName enumSource = ButtonName.valueForString(example);
+ example = "SHUFFLE";
+ ButtonName enumShuffle = ButtonName.valueForString(example);
+ example = "REPEAT";
+ ButtonName enumRepeat = ButtonName.valueForString(example);
+
+
assertNotNull("OK returned null", enumOk);
assertNotNull("SEEKLEFT returned null", enumSeekLeft);
@@ -71,6 +108,24 @@ public class ButtonNameTests extends TestCase {
assertNotNull("PRESET_9 returned null", enumPreset9);
assertNotNull("CUSTOM_BUTTON returned null", enumCustomButton);
assertNotNull("SEARCH returned null", enumSearch);
+ assertNotNull("AC_MAX returned null", enumAcMax);
+ assertNotNull("AC returned null", enumAc);
+ assertNotNull("RECIRCULATE returned null", enumRecirculate);
+ assertNotNull("FAN_UP returned null", enumFanUp);
+ assertNotNull("FAN_DOWN returned null", enumFanDown);
+ assertNotNull("TEMP_UP returned null", enumTempUp);
+ assertNotNull("TEMP_DOWN returned null", enumTempDown);
+ assertNotNull("DEFROST_MAX returned null", enumDefrostMax);
+ assertNotNull("DEFROST returned null", enumDefrost);
+ assertNotNull("DEFROST_REAR returned null", enumDefrostRear);
+ assertNotNull("UPPER_VENT returned null", enumUpperVent);
+ assertNotNull("LOWER_VENT returned null", enumLowerVent);
+ assertNotNull("VOLUME_UP returned null", enumVolumeUp);
+ assertNotNull("VOLUME_DOWN returned null", enumVolumeDown);
+ assertNotNull("EJECT returned null", enumEject);
+ assertNotNull("SOURCE returned null", enumSource);
+ assertNotNull("SHUFFLE returned null", enumShuffle);
+ assertNotNull("REPEAT returned null", enumRepeat);
}
/**
@@ -125,7 +180,25 @@ public class ButtonNameTests extends TestCase {
enumTestList.add(ButtonName.PRESET_8);
enumTestList.add(ButtonName.PRESET_9);
enumTestList.add(ButtonName.CUSTOM_BUTTON);
- enumTestList.add(ButtonName.SEARCH);
+ enumTestList.add(ButtonName.SEARCH);
+ enumTestList.add(ButtonName.AC_MAX);
+ enumTestList.add(ButtonName.AC);
+ enumTestList.add(ButtonName.RECIRCULATE);
+ enumTestList.add(ButtonName.FAN_UP);
+ enumTestList.add(ButtonName.FAN_DOWN);
+ enumTestList.add(ButtonName.TEMP_UP);
+ enumTestList.add(ButtonName.TEMP_DOWN);
+ enumTestList.add(ButtonName.DEFROST_MAX);
+ enumTestList.add(ButtonName.DEFROST);
+ enumTestList.add(ButtonName.DEFROST_REAR);
+ enumTestList.add(ButtonName.UPPER_VENT);
+ enumTestList.add(ButtonName.LOWER_VENT);
+ enumTestList.add(ButtonName.VOLUME_UP);
+ enumTestList.add(ButtonName.VOLUME_DOWN);
+ enumTestList.add(ButtonName.EJECT);
+ enumTestList.add(ButtonName.SOURCE);
+ enumTestList.add(ButtonName.SHUFFLE);
+ enumTestList.add(ButtonName.REPEAT);
assertTrue("Enum value list does not match enum class list",
enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/DefrostZoneTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/DefrostZoneTests.java
new file mode 100644
index 000000000..f1f375623
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/DefrostZoneTests.java
@@ -0,0 +1,79 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.DefrostZone}
+ */
+public class DefrostZoneTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "FRONT";
+ DefrostZone enumFront = DefrostZone.valueForString(example);
+ example = "REAR";
+ DefrostZone enumRear = DefrostZone.valueForString(example);
+ example = "ALL";
+ DefrostZone enumAll = DefrostZone.valueForString(example);
+ example = "NONE";
+ DefrostZone enumNone = DefrostZone.valueForString(example);
+
+ assertNotNull("FRONT returned null", enumFront);
+ assertNotNull("REAR returned null", enumRear);
+ assertNotNull("ALL returned null", enumAll);
+ assertNotNull("NONE returned null", enumNone);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "fRONT";
+ try {
+ DefrostZone temp = DefrostZone.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ DefrostZone temp = DefrostZone.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of DefrostZone.
+ */
+ public void testListEnum() {
+ List<DefrostZone> enumValueList = Arrays.asList(DefrostZone.values());
+
+ List<DefrostZone> enumTestList = new ArrayList<DefrostZone>();
+ enumTestList.add(DefrostZone.FRONT);
+ enumTestList.add(DefrostZone.REAR);
+ enumTestList.add(DefrostZone.ALL);
+ enumTestList.add(DefrostZone.NONE);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ModuleTypeTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ModuleTypeTests.java
new file mode 100644
index 000000000..18a47b79d
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ModuleTypeTests.java
@@ -0,0 +1,71 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.ModuleType}
+ */
+public class ModuleTypeTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "CLIMATE";
+ ModuleType enumClimate = ModuleType.valueForString(example);
+ example = "RADIO";
+ ModuleType enumRadio = ModuleType.valueForString(example);
+
+ assertNotNull("CLIMATE returned null", enumClimate);
+ assertNotNull("RADIO returned null", enumRadio);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "cLIMATE";
+ try {
+ ModuleType temp = ModuleType.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ ModuleType temp = ModuleType.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of ModuleType.
+ */
+ public void testListEnum() {
+ List<ModuleType> enumValueList = Arrays.asList(ModuleType.values());
+
+ List<ModuleType> enumTestList = new ArrayList<ModuleType>();
+ enumTestList.add(ModuleType.CLIMATE);
+ enumTestList.add(ModuleType.RADIO);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioBandTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioBandTests.java
new file mode 100644
index 000000000..cc5d5b700
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioBandTests.java
@@ -0,0 +1,75 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.RadioBand;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.RadioBand}
+ */
+public class RadioBandTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "AM";
+ RadioBand enumAm = RadioBand.valueForString(example);
+ example = "FM";
+ RadioBand enumFm = RadioBand.valueForString(example);
+ example = "XM";
+ RadioBand enumXm = RadioBand.valueForString(example);
+
+ assertNotNull("AM returned null", enumAm);
+ assertNotNull("FM returned null", enumFm);
+ assertNotNull("XM returned null", enumXm);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "aM";
+ try {
+ RadioBand temp = RadioBand.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ RadioBand temp = RadioBand.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of RadioBand.
+ */
+ public void testListEnum() {
+ List<RadioBand> enumValueList = Arrays.asList(RadioBand.values());
+
+ List<RadioBand> enumTestList = new ArrayList<RadioBand>();
+ enumTestList.add(RadioBand.AM);
+ enumTestList.add(RadioBand.FM);
+ enumTestList.add(RadioBand.XM);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioStateTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioStateTests.java
new file mode 100644
index 000000000..d16f00599
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/RadioStateTests.java
@@ -0,0 +1,79 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.RadioState;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.RadioState}
+ */
+public class RadioStateTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "ACQUIRING";
+ RadioState enumAcquiring = RadioState.valueForString(example);
+ example = "ACQUIRED";
+ RadioState enumAcquired = RadioState.valueForString(example);
+ example = "MULTICAST";
+ RadioState enumMultiCast = RadioState.valueForString(example);
+ example = "NOT_FOUND";
+ RadioState enumNotFound = RadioState.valueForString(example);
+
+ assertNotNull("ACQUIRING returned null", enumAcquiring);
+ assertNotNull("ACQUIRED returned null", enumAcquired);
+ assertNotNull("MULTICAST returned null", enumMultiCast);
+ assertNotNull("NOT_FOUND returned null", enumNotFound);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "aCQUIRING";
+ try {
+ RadioState temp = RadioState.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ RadioState temp = RadioState.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of RadioState.
+ */
+ public void testListEnum() {
+ List<RadioState> enumValueList = Arrays.asList(RadioState.values());
+
+ List<RadioState> enumTestList = new ArrayList<RadioState>();
+ enumTestList.add(RadioState.ACQUIRING);
+ enumTestList.add(RadioState.ACQUIRED);
+ enumTestList.add(RadioState.MULTICAST);
+ enumTestList.add(RadioState.NOT_FOUND);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
index 3eaae9937..5156c4f44 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/ResultTests.java
@@ -82,6 +82,10 @@ public class ResultTests extends TestCase {
Result enumExpiredCert = Result.valueForString(example);
example = "RESUME_FAILED";
Result enumResumeFailed = Result.valueForString(example);
+ example = "DATA_NOT_AVAILABLE";
+ Result enumDataNotAvailable = Result.valueForString(example);
+ example = "READ_ONLY";
+ Result enumReadOnly = Result.valueForString(example);
assertNotNull("SUCCESS returned null", enumSuccess);
assertNotNull("INVALID_DATA returned null", enumInvalidData);
@@ -115,6 +119,8 @@ public class ResultTests extends TestCase {
assertNotNull("INVALID_CERT returned null", enumInvalidCert);
assertNotNull("EXPIRED_CERT returned null", enumExpiredCert);
assertNotNull("RESUME_FAILED returned null", enumResumeFailed);
+ assertNotNull("DATA_NOT_AVAILABLE returned null", enumDataNotAvailable);
+ assertNotNull("READ_ONLY returned null", enumReadOnly);
}
/**
@@ -183,7 +189,9 @@ public class ResultTests extends TestCase {
enumTestList.add(Result.SAVED);
enumTestList.add(Result.INVALID_CERT);
enumTestList.add(Result.EXPIRED_CERT);
- enumTestList.add(Result.RESUME_FAILED);
+ enumTestList.add(Result.RESUME_FAILED);
+ enumTestList.add(Result.DATA_NOT_AVAILABLE);
+ enumTestList.add(Result.READ_ONLY);
assertTrue("Enum value list does not match enum class list",
enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/SystemCapabilityTypeTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/SystemCapabilityTypeTests.java
new file mode 100644
index 000000000..f17f3cbd3
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/SystemCapabilityTypeTests.java
@@ -0,0 +1,115 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.SystemCapabilityType}
+ */
+public class SystemCapabilityTypeTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "NAVIGATION";
+ SystemCapabilityType enumNavigation = SystemCapabilityType.valueForString(example);
+ example = "PHONE_CALL";
+ SystemCapabilityType enumPhoneCall = SystemCapabilityType.valueForString(example);
+ example = "VIDEO_STREAMING";
+ SystemCapabilityType enumVideoStreaming = SystemCapabilityType.valueForString(example);
+ example = "REMOTE_CONTROL";
+ SystemCapabilityType enumRemoteControl = SystemCapabilityType.valueForString(example);
+ example = "HMI";
+ SystemCapabilityType enumHmi = SystemCapabilityType.valueForString(example);
+ example = "DISPLAY";
+ SystemCapabilityType enumDisplay = SystemCapabilityType.valueForString(example);
+ example = "AUDIO_PASSTHROUGH";
+ SystemCapabilityType enumAudioPassThrough = SystemCapabilityType.valueForString(example);
+ example = "BUTTON";
+ SystemCapabilityType enumButton = SystemCapabilityType.valueForString(example);
+ example = "HMI_ZONE";
+ SystemCapabilityType enumHmiZone = SystemCapabilityType.valueForString(example);
+ example = "PRESET_BANK";
+ SystemCapabilityType enumPresetBank = SystemCapabilityType.valueForString(example);
+ example = "SOFTBUTTON";
+ SystemCapabilityType enumSoftButton = SystemCapabilityType.valueForString(example);
+ example = "SPEECH";
+ SystemCapabilityType enumSpeech = SystemCapabilityType.valueForString(example);
+ example = "VOICE_RECOGNITION";
+ SystemCapabilityType enumVoiceRecognition = SystemCapabilityType.valueForString(example);
+
+ assertNotNull("NAVIGATION returned null", enumNavigation);
+ assertNotNull("PHONE_CALL returned null", enumPhoneCall);
+ assertNotNull("VIDEO_STREAMING returned null", enumVideoStreaming);
+ assertNotNull("REMOTE_CONTROL returned null", enumRemoteControl);
+ assertNotNull("HMI returned null", enumHmi);
+ assertNotNull("DISPLAY returned null", enumDisplay);
+ assertNotNull("AUDIO_PASSTHROUGH returned null", enumAudioPassThrough);
+ assertNotNull("BUTTON returned null", enumButton);
+ assertNotNull("HMI_ZONE returned null", enumHmiZone);
+ assertNotNull("PRESET_BANK returned null", enumPresetBank);
+ assertNotNull("SOFTBUTTON returned null", enumSoftButton);
+ assertNotNull("SPEECH returned null", enumSpeech);
+ assertNotNull("VOICE_RECOGNITION returned null", enumVoiceRecognition);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "nAVIGATION";
+ try {
+ SystemCapabilityType temp = SystemCapabilityType.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ SystemCapabilityType temp = SystemCapabilityType.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of SystemCapabilityType.
+ */
+ public void testListEnum() {
+ List<SystemCapabilityType> enumValueList = Arrays.asList(SystemCapabilityType.values());
+
+ List<SystemCapabilityType> enumTestList = new ArrayList<SystemCapabilityType>();
+ enumTestList.add(SystemCapabilityType.NAVIGATION);
+ enumTestList.add(SystemCapabilityType.PHONE_CALL);
+ enumTestList.add(SystemCapabilityType.VIDEO_STREAMING);
+ enumTestList.add(SystemCapabilityType.REMOTE_CONTROL);
+ enumTestList.add(SystemCapabilityType.HMI);
+ enumTestList.add(SystemCapabilityType.DISPLAY);
+ enumTestList.add(SystemCapabilityType.AUDIO_PASSTHROUGH);
+ enumTestList.add(SystemCapabilityType.BUTTON);
+ enumTestList.add(SystemCapabilityType.HMI_ZONE);
+ enumTestList.add(SystemCapabilityType.PRESET_BANK);
+ enumTestList.add(SystemCapabilityType.SOFTBUTTON);
+ enumTestList.add(SystemCapabilityType.SPEECH);
+ enumTestList.add(SystemCapabilityType.VOICE_RECOGNITION);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VentilationModeTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VentilationModeTests.java
new file mode 100644
index 000000000..561e66a77
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/enums/VentilationModeTests.java
@@ -0,0 +1,79 @@
+package com.smartdevicelink.test.rpc.enums;
+
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.enums.VentilationMode}
+ */
+public class VentilationModeTests extends TestCase {
+
+ /**
+ * Verifies that the enum values are not null upon valid assignment.
+ */
+ public void testValidEnums () {
+ String example = "UPPER";
+ VentilationMode enumUpper = VentilationMode.valueForString(example);
+ example = "LOWER";
+ VentilationMode enumLower = VentilationMode.valueForString(example);
+ example = "BOTH";
+ VentilationMode enumBoth = VentilationMode.valueForString(example);
+ example = "NONE";
+ VentilationMode enumNone = VentilationMode.valueForString(example);
+
+ assertNotNull("UPPER returned null", enumUpper);
+ assertNotNull("LOWER returned null", enumLower);
+ assertNotNull("BOTH returned null", enumBoth);
+ assertNotNull("NONE returned null", enumNone);
+ }
+
+ /**
+ * Verifies that an invalid assignment is null.
+ */
+ public void testInvalidEnum () {
+ String example = "uPPER";
+ try {
+ VentilationMode temp = VentilationMode.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (IllegalArgumentException exception) {
+ fail("Invalid enum throws IllegalArgumentException.");
+ }
+ }
+
+ /**
+ * Verifies that a null assignment is invalid.
+ */
+ public void testNullEnum () {
+ String example = null;
+ try {
+ VentilationMode temp = VentilationMode.valueForString(example);
+ assertNull("Result of valueForString should be null.", temp);
+ }
+ catch (NullPointerException exception) {
+ fail("Null string throws NullPointerException.");
+ }
+ }
+
+ /**
+ * Verifies the possible enum values of VentilationMode.
+ */
+ public void testListEnum() {
+ List<VentilationMode> enumValueList = Arrays.asList(VentilationMode.values());
+
+ List<VentilationMode> enumTestList = new ArrayList<VentilationMode>();
+ enumTestList.add(VentilationMode.UPPER);
+ enumTestList.add(VentilationMode.LOWER);
+ enumTestList.add(VentilationMode.BOTH);
+ enumTestList.add(VentilationMode.NONE);
+
+ assertTrue("Enum value list does not match enum class list",
+ enumValueList.containsAll(enumTestList) && enumTestList.containsAll(enumValueList));
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/notifications/OnInteriorVehicleDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/notifications/OnInteriorVehicleDataTests.java
new file mode 100644
index 000000000..4fded53fe
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/notifications/OnInteriorVehicleDataTests.java
@@ -0,0 +1,69 @@
+package com.smartdevicelink.test.rpc.notifications;
+
+import com.smartdevicelink.marshal.JsonRPCMarshaller;
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCMessage;
+import com.smartdevicelink.proxy.rpc.ModuleData;
+import com.smartdevicelink.proxy.rpc.OnInteriorVehicleData;
+import com.smartdevicelink.test.BaseRpcTests;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * This is a unit test class for the SmartDeviceLink library project class :
+ * {@link com.smartdevicelink.rpc.OnInteriorVehicleData}
+ */
+public class OnInteriorVehicleDataTests extends BaseRpcTests{
+
+ @Override
+ protected RPCMessage createMessage(){
+ OnInteriorVehicleData msg = new OnInteriorVehicleData();
+ msg.setModuleData(Test.GENERAL_MODULEDATA);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_NOTIFICATION;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.ON_INTERIOR_VEHICLE_DATA.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(OnInteriorVehicleData.KEY_MODULE_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_MODULEDATA.getStore()));
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleData moduleData = ( (OnInteriorVehicleData) msg ).getModuleData();
+
+ // Valid Tests
+ assertTrue(Test.TRUE, Validator.validateModuleData(Test.GENERAL_MODULEDATA, moduleData));
+
+ // Invalid/Null Tests
+ OnInteriorVehicleData msg = new OnInteriorVehicleData();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getModuleData());
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ButtonPressTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ButtonPressTests.java
new file mode 100644
index 000000000..f16a3a87c
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/ButtonPressTests.java
@@ -0,0 +1,113 @@
+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.ButtonPress;
+import com.smartdevicelink.proxy.rpc.enums.ButtonName;
+import com.smartdevicelink.proxy.rpc.enums.ButtonPressMode;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+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.rpc.ButtonPress}
+ */
+public class ButtonPressTests extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+ ButtonPress msg = new ButtonPress();
+
+ msg.setModuleType(Test.GENERAL_MODULETYPE);
+ msg.setButtonPressMode(Test.GENERAL_BUTTONPRESSMODE);
+ msg.setButtonName(Test.GENERAL_BUTTONNAME);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_REQUEST;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.BUTTON_PRESS.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(ButtonPress.KEY_MODULE_TYPE, Test.GENERAL_MODULETYPE);
+ result.put(ButtonPress.KEY_BUTTON_NAME, Test.GENERAL_BUTTONNAME);
+ result.put(ButtonPress.KEY_BUTTON_PRESS_MODE, Test.GENERAL_BUTTONPRESSMODE);
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleType testModuleType = ( (ButtonPress) msg ).getModuleType();
+ ButtonName testButtonName = ( (ButtonPress) msg ).getButtonName();
+ ButtonPressMode testButtonPressMode = ( (ButtonPress) msg ).getButtonPressMode();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_MODULETYPE, testModuleType);
+ assertEquals(Test.MATCH, Test.GENERAL_BUTTONNAME, testButtonName);
+ assertEquals(Test.MATCH, Test.GENERAL_BUTTONPRESSMODE, testButtonPressMode);
+
+ // Invalid/Null Tests
+ ButtonPress msg = new ButtonPress();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getModuleType());
+ assertNull(Test.NULL, msg.getButtonName());
+ assertNull(Test.NULL, msg.getButtonPressMode());
+ }
+
+ /**
+ * 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);
+ ButtonPress cmd = new ButtonPress(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);
+
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, ButtonPress.KEY_MODULE_TYPE).toString(), cmd.getModuleType().toString());
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, ButtonPress.KEY_BUTTON_NAME).toString(), cmd.getButtonName().toString());
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, ButtonPress.KEY_BUTTON_PRESS_MODE).toString(), cmd.getButtonPressMode().toString());
+ }catch (JSONException e) {
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/GetInteriorVehicleDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/GetInteriorVehicleDataTests.java
new file mode 100644
index 000000000..5a08d4266
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/GetInteriorVehicleDataTests.java
@@ -0,0 +1,105 @@
+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.GetInteriorVehicleData;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+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.rpc.GetInteriorVehicleData}
+ */
+public class GetInteriorVehicleDataTests extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+ GetInteriorVehicleData msg = new GetInteriorVehicleData();
+
+ msg.setModuleType(Test.GENERAL_MODULETYPE);
+ msg.setSubscribe(Test.GENERAL_BOOLEAN);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_REQUEST;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.GET_INTERIOR_VEHICLE_DATA.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(GetInteriorVehicleData.KEY_MODULE_TYPE, Test.GENERAL_MODULETYPE);
+ result.put(GetInteriorVehicleData.KEY_SUBSCRIBE, Test.GENERAL_BOOLEAN);
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleType testModuleType = ( (GetInteriorVehicleData) msg ).getModuleType();
+ boolean testSubscribed = ( (GetInteriorVehicleData) msg ).getSubscribe();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_MODULETYPE, testModuleType);
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, testSubscribed);
+
+ // Invalid/Null Tests
+ GetInteriorVehicleData msg = new GetInteriorVehicleData();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getModuleType());
+ assertNull(Test.NULL, msg.getSubscribe());
+ }
+
+ /**
+ * 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);
+ GetInteriorVehicleData cmd = new GetInteriorVehicleData(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);
+
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, GetInteriorVehicleData.KEY_MODULE_TYPE).toString(), cmd.getModuleType().toString());
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, GetInteriorVehicleData.KEY_SUBSCRIBE), cmd.getSubscribe());
+ }catch (JSONException e) {
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/SetInteriorVehicleDataTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/SetInteriorVehicleDataTests.java
new file mode 100644
index 000000000..f5ecb0d06
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/requests/SetInteriorVehicleDataTests.java
@@ -0,0 +1,102 @@
+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.ModuleData;
+import com.smartdevicelink.proxy.rpc.SetInteriorVehicleData;
+import com.smartdevicelink.test.BaseRpcTests;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+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.rpc.SetInteriorVehicleData}
+ */
+public class SetInteriorVehicleDataTests extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+ SetInteriorVehicleData msg = new SetInteriorVehicleData();
+
+ msg.setModuleData(Test.GENERAL_MODULEDATA);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_REQUEST;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.SET_INTERIOR_VEHICLE_DATA.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(SetInteriorVehicleData.KEY_MODULE_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_MODULEDATA.getStore()));
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleData testModuleData = ( (SetInteriorVehicleData) msg ).getModuleData();
+
+ // Valid Tests
+ assertTrue(Test.TRUE, Validator.validateModuleData(Test.GENERAL_MODULEDATA, testModuleData));
+
+ // Invalid/Null Tests
+ SetInteriorVehicleData msg = new SetInteriorVehicleData();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getModuleData());
+ }
+
+ /**
+ * 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);
+ SetInteriorVehicleData cmd = new SetInteriorVehicleData(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);
+
+ ModuleData referenceModuleData = new ModuleData(JsonRPCMarshaller.deserializeJSONObject((JSONObject) JsonUtils.readObjectFromJsonObject(parameters, SetInteriorVehicleData.KEY_MODULE_DATA)));
+
+ assertTrue(Test.TRUE, Validator.validateModuleData(referenceModuleData, cmd.getModuleData()));
+ }catch (JSONException e) {
+ fail(Test.JSON_FAIL);
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ButtonPressResponseTest.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ButtonPressResponseTest.java
new file mode 100644
index 000000000..64f5b0c75
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/ButtonPressResponseTest.java
@@ -0,0 +1,74 @@
+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.ButtonPressResponse;
+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.rpc.ButtonPressResponse}
+ */
+public class ButtonPressResponseTest extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+ return new ButtonPressResponse();
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_RESPONSE;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.BUTTON_PRESS.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ return new JSONObject();
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Invalid/Null Tests
+ ButtonPressResponse msg = new ButtonPressResponse();
+ 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);
+ ButtonPressResponse cmd = new ButtonPressResponse(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();
+ }
+ }
+} \ No newline at end of file
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/GetInteriorVehicleDataResponseTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/GetInteriorVehicleDataResponseTests.java
new file mode 100644
index 000000000..c76388c69
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/GetInteriorVehicleDataResponseTests.java
@@ -0,0 +1,110 @@
+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.GetInteriorVehicleDataResponse;
+import com.smartdevicelink.proxy.rpc.ModuleData;
+import com.smartdevicelink.test.BaseRpcTests;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+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.rpc.GetInteriorVehicleDataResponse}
+ */
+public class GetInteriorVehicleDataResponseTests extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+
+ GetInteriorVehicleDataResponse msg = new GetInteriorVehicleDataResponse();
+
+ msg.setIsSubscribed(Test.GENERAL_BOOLEAN);
+ msg.setModuleData(Test.GENERAL_MODULEDATA);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_RESPONSE;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.GET_INTERIOR_VEHICLE_DATA.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED, Test.GENERAL_BOOLEAN);
+ result.put(GetInteriorVehicleDataResponse.KEY_MODULE_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_MODULEDATA.getStore()));
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ boolean testIsSubscribed = ( (GetInteriorVehicleDataResponse) msg ).getIsSubscribed();
+ ModuleData testModuleData = ( (GetInteriorVehicleDataResponse) msg ).getModuleData();
+
+ // Valid Tests
+ assertEquals(Test.MATCH, Test.GENERAL_BOOLEAN, testIsSubscribed);
+ assertTrue(Test.TRUE, Validator.validateModuleData(Test.GENERAL_MODULEDATA, testModuleData));
+
+ // Invalid/Null Tests
+ GetInteriorVehicleDataResponse msg = new GetInteriorVehicleDataResponse();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getIsSubscribed());
+ assertNull(Test.NULL, msg.getModuleData());
+ }
+
+ /**
+ * 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);
+ GetInteriorVehicleDataResponse cmd = new GetInteriorVehicleDataResponse (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);
+
+ ModuleData testModuleData = new ModuleData(JsonRPCMarshaller.deserializeJSONObject((JSONObject) JsonUtils.readObjectFromJsonObject(parameters, GetInteriorVehicleDataResponse.KEY_MODULE_DATA)));
+ ModuleData cmdModuleData = cmd.getModuleData();
+
+ assertTrue(Test.TRUE, Validator.validateModuleData(testModuleData, cmdModuleData) );
+ assertEquals(Test.MATCH, JsonUtils.readObjectFromJsonObject(parameters, GetInteriorVehicleDataResponse.KEY_IS_SUBSCRIBED), cmd.getIsSubscribed());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/SetInteriorVehicleDataResponseTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/SetInteriorVehicleDataResponseTests.java
new file mode 100644
index 000000000..c25685157
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/rpc/responses/SetInteriorVehicleDataResponseTests.java
@@ -0,0 +1,104 @@
+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.ModuleData;
+import com.smartdevicelink.proxy.rpc.SetInteriorVehicleDataResponse;
+import com.smartdevicelink.test.BaseRpcTests;
+import com.smartdevicelink.test.JsonUtils;
+import com.smartdevicelink.test.Test;
+import com.smartdevicelink.test.Validator;
+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.rpc.SetInteriorVehicleDataResponse}
+ */
+public class SetInteriorVehicleDataResponseTests extends BaseRpcTests {
+
+ @Override
+ protected RPCMessage createMessage(){
+
+ SetInteriorVehicleDataResponse msg = new SetInteriorVehicleDataResponse();
+
+ msg.setModuleData(Test.GENERAL_MODULEDATA);
+
+ return msg;
+ }
+
+ @Override
+ protected String getMessageType(){
+ return RPCMessage.KEY_RESPONSE;
+ }
+
+ @Override
+ protected String getCommandType(){
+ return FunctionID.SET_INTERIOR_VEHICLE_DATA.toString();
+ }
+
+ @Override
+ protected JSONObject getExpectedParameters(int sdlVersion){
+ JSONObject result = new JSONObject();
+
+ try{
+ result.put(SetInteriorVehicleDataResponse.KEY_MODULE_DATA, JsonRPCMarshaller.serializeHashtable(Test.GENERAL_MODULEDATA.getStore()));
+ }catch(JSONException e){
+ fail(Test.JSON_FAIL);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests the expected values of the RPC message.
+ */
+ public void testRpcValues () {
+ // Test Values
+ ModuleData testModuleData = ( (SetInteriorVehicleDataResponse) msg ).getModuleData();
+
+ // Valid Tests
+ assertTrue(Test.TRUE, Validator.validateModuleData(Test.GENERAL_MODULEDATA, testModuleData));
+
+ // Invalid/Null Tests
+ SetInteriorVehicleDataResponse msg = new SetInteriorVehicleDataResponse();
+ assertNotNull(Test.NOT_NULL, msg);
+ testNullBase(msg);
+
+ assertNull(Test.NULL, msg.getModuleData());
+ }
+
+ /**
+ * 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);
+ SetInteriorVehicleDataResponse cmd = new SetInteriorVehicleDataResponse (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);
+
+ ModuleData testModuleData = new ModuleData(JsonRPCMarshaller.deserializeJSONObject((JSONObject) JsonUtils.readObjectFromJsonObject(parameters, SetInteriorVehicleDataResponse.KEY_MODULE_DATA)));
+ ModuleData cmdModuleData = cmd.getModuleData();
+
+ assertTrue(Test.TRUE, Validator.validateModuleData(testModuleData, cmdModuleData) );
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/security/SdlSecurityBaseTest.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/security/SdlSecurityBaseTest.java
index 56a482804..2bf6136fa 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/security/SdlSecurityBaseTest.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/security/SdlSecurityBaseTest.java
@@ -74,7 +74,7 @@ public class SdlSecurityBaseTest extends AndroidTestCase {
}
@Override
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
}
@Override
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/AbstractPacketizerTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/AbstractPacketizerTests.java
index e05091c44..80126c67c 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/AbstractPacketizerTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/AbstractPacketizerTests.java
@@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
+import java.util.List;
import junit.framework.TestCase;
@@ -118,7 +119,7 @@ class MockInterfaceBroker implements ISdlConnectionListener {
}
@Override
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
}
@Override
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/RTPH264PacketizerTest.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/RTPH264PacketizerTest.java
new file mode 100644
index 000000000..70274444c
--- /dev/null
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/RTPH264PacketizerTest.java
@@ -0,0 +1,881 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.test.streaming;
+
+import com.smartdevicelink.SdlConnection.SdlSession;
+import com.smartdevicelink.protocol.ProtocolMessage;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
+import com.smartdevicelink.streaming.IStreamListener;
+import com.smartdevicelink.streaming.RTPH264Packetizer;
+import com.smartdevicelink.transport.BTTransportConfig;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * This class includes a unit test for {@link com.smartdevicelink.streaming.RTPH264Packetizer}.
+ *
+ * @author Sho Amano
+ */
+public class RTPH264PacketizerTest extends TestCase {
+
+ private static final int FRAME_LENGTH_LEN = 2;
+ private static final int RTP_HEADER_LEN = 12;
+
+ private static final byte WIPRO_VERSION = 0x0B;
+ private static final byte SESSION_ID = 0x0A;
+
+ private class ByteStreamNALUnit {
+ byte[] startCode;
+ byte[] nalUnit;
+ int frameNum;
+
+ ByteStreamNALUnit(byte[] startCode, byte[] nalUnit, int frameNum) {
+ this.startCode = startCode;
+ this.nalUnit = nalUnit;
+ this.frameNum = frameNum;
+ }
+
+ byte[] createArray() {
+ byte[] array = new byte[startCode.length + nalUnit.length];
+ System.arraycopy(startCode, 0, array, 0, startCode.length);
+ System.arraycopy(nalUnit, 0, array, startCode.length, nalUnit.length);
+ return array;
+ }
+
+ public int getLength() {
+ return startCode.length + nalUnit.length;
+ }
+ }
+
+ private static final byte[] START_CODE_3 = {0x00, 0x00, 0x01};
+ private static final byte[] START_CODE_4 = {0x00, 0x00, 0x00, 0x01};
+
+ /* a sample H.264 stream, including 33 frames of 16px white square */
+ private final ByteStreamNALUnit[] SAMPLE_STREAM = new ByteStreamNALUnit[] {
+ // SPS
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60}, 0),
+ // PPS
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20}, 0),
+ // I
+ new ByteStreamNALUnit(START_CODE_3, new byte[]{0x65, (byte)0x88, (byte)0x82, 0x07, 0x67, 0x39, 0x31, 0x40,
+ 0x00, 0x5E, 0x0A, (byte)0xFB, (byte)0xEF, (byte)0xAE, (byte)0xBA, (byte)0xEB,
+ (byte)0xAE, (byte)0xBA, (byte)0xEB, (byte)0xC0}, 0),
+ // P
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x1C, 0x0E, (byte)0xCE, 0x71, (byte)0xB0}, 1),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x2A, 0x03, (byte)0xB3, (byte)0x9C, 0x6C}, 2),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x3B, 0x03, (byte)0xB3, (byte)0x9C, 0x6C}, 3),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x49, 0x00, (byte)0xEC, (byte)0xE7, 0x1B}, 4),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x59, 0x40, (byte)0xEC, (byte)0xE7, 0x1B}, 5),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x69, (byte)0x80, (byte)0xEC, (byte)0xE7, 0x1B}, 6),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x79, (byte)0xC0, (byte)0xEC, (byte)0xE7, 0x1B}, 7),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0x88, (byte)0x80, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 8),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0x98, (byte)0x90, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 9),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xA8, (byte)0xA0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 10),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xB8, (byte)0xB0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 11),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xC8, (byte)0xC0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 12),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xD8, (byte)0xD0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 13),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xE8, (byte)0xE0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 14),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, (byte)0xF8, (byte)0xF0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0}, 15),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x00, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 16),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x10, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 17),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x20, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 18),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x30, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 19),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x40, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 20),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x50, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 21),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x60, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 22),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, 0x70, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 23),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0x80, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 24),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0x90, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 25),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0xA0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 26),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0xB0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 27),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0xC0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 28),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9B, (byte)0xD0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60}, 29),
+ // SPS
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60}, 30),
+ // PPS
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20}, 30),
+ // I
+ new ByteStreamNALUnit(START_CODE_3, new byte[]{0x65, (byte)0x88, (byte)0x81, 0x00, (byte)0x8E, 0x73, (byte)0x93, 0x14,
+ 0x00, 0x06, (byte)0xA4, 0x2F, (byte)0xBE, (byte)0xFA, (byte)0xEB, (byte)0xAE,
+ (byte)0xBA, (byte)0xEB, (byte)0xAE, (byte)0xBC}, 30),
+ // P
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x1C, 0x0D, (byte)0xCE, 0x71, (byte)0xB0}, 31),
+ new ByteStreamNALUnit(START_CODE_4, new byte[]{0x41, (byte)0x9A, 0x2A, 0x03, 0x33, (byte)0x9C, 0x6C}, 32),
+ };
+
+ /**
+ * Test for creating Single Frame RTP packets from H.264 byte stream
+ */
+ public void testSingleFrames() {
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for creating Single Frame RTP packets then splitting into multiple SDL frames
+ */
+ public void testSingleFramesIntoMultipleMessages() {
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+
+ // try to modify "bufferSize" variable (in AbstractPacketizer)
+ Class packetizerClass = RTPH264Packetizer.class;
+ String fieldName = "bufferSize";
+ java.lang.reflect.Field bufferSizeField = null;
+ while (packetizerClass != null) {
+ try {
+ bufferSizeField = packetizerClass.getDeclaredField(fieldName);
+ break;
+ } catch (NoSuchFieldException e) {
+ packetizerClass = packetizerClass.getSuperclass();
+ }
+ }
+ if (bufferSizeField != null) {
+ try {
+ bufferSizeField.setAccessible(true);
+ // use small MTU and make some RTP packets split into multiple SDL frames
+ bufferSizeField.set(packetizer, FRAME_LENGTH_LEN + RTP_HEADER_LEN + 16);
+ } catch (IllegalAccessException e) {
+ fail("Cannot access to private field \"" + fieldName + "\".");
+ }
+ } else {
+ fail("Cannot find private field \"" + fieldName + "\".");
+ }
+
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for creating Fragmentation Units from H.264 byte stream
+ */
+ public void testFragmentationUnits() {
+ ByteStreamNALUnit[] stream = new ByteStreamNALUnit[] {
+ SAMPLE_STREAM[0], SAMPLE_STREAM[1], null, null, null, SAMPLE_STREAM[5]
+ };
+ byte[] fakeNALUnit1 = new byte[65535 - RTP_HEADER_LEN]; // not fragmented
+ byte[] fakeNALUnit2 = new byte[65536 - RTP_HEADER_LEN]; // will be fragmented
+ byte[] fakeNALUnit3 = new byte[65537 - RTP_HEADER_LEN]; // ditto
+
+ for (int i = 0; i < fakeNALUnit1.length; i++) {
+ fakeNALUnit1[i] = (byte)(i % 256);
+ }
+ for (int i = 0; i < fakeNALUnit2.length; i++) {
+ fakeNALUnit2[i] = (byte)(i % 256);
+ }
+ for (int i = 0; i < fakeNALUnit3.length; i++) {
+ fakeNALUnit3[i] = (byte)(i % 256);
+ }
+
+ stream[2] = new ByteStreamNALUnit(START_CODE_3, fakeNALUnit1, 0);
+ stream[3] = new ByteStreamNALUnit(START_CODE_4, fakeNALUnit2, 1);
+ stream[4] = new ByteStreamNALUnit(START_CODE_4, fakeNALUnit3, 2);
+
+ StreamVerifier verifier = new StreamVerifier(stream);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(stream);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(stream.length + 2, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for RTP sequence number gets wrap-around correctly
+ */
+ public void testSequenceNumWrapAround() {
+ ByteStreamNALUnit[] stream = new ByteStreamNALUnit[70000];
+ for (int i = 0; i < stream.length; i++) {
+ stream[i] = new ByteStreamNALUnit(START_CODE_4, SAMPLE_STREAM[3].nalUnit, i);
+ }
+
+ StreamVerifier verifier = new StreamVerifier(stream);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(stream);
+ try {
+ Thread.sleep(2000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(stream.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#setPayloadType(byte)}
+ */
+ public void testSetPayloadType() {
+ byte pt = (byte)123;
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM, pt);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ packetizer.setPayloadType(pt);
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#setSSRC(int)}
+ */
+ public void testSetSSRC() {
+ int ssrc = 0xFEDCBA98;
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ verifier.setExpectedSSRC(ssrc);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ packetizer.setSSRC(ssrc);
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#pause()} and
+ * {@link com.smartdevicelink.streaming.RTPH264Packetizer#resume()}
+ */
+ public void testPauseResume() {
+ int index = 0;
+ // split SAMPLE_STREAM into three parts
+ ByteStreamNALUnit[] inputStream1 = new ByteStreamNALUnit[8];
+ ByteStreamNALUnit[] inputStream2 = new ByteStreamNALUnit[19];
+ ByteStreamNALUnit[] inputStream3 = new ByteStreamNALUnit[10];
+ for (int i = 0; i < inputStream1.length; i++) {
+ inputStream1[i] = SAMPLE_STREAM[index++];
+ }
+ for (int i = 0; i < inputStream2.length; i++) {
+ inputStream2[i] = SAMPLE_STREAM[index++];
+ }
+ for (int i = 0; i < inputStream3.length; i++) {
+ inputStream3[i] = SAMPLE_STREAM[index++];
+ }
+
+ index = 0;
+ // expected output is "all NAL units in inputStream1" plus "I frame and onwards in inputStream3"
+ ByteStreamNALUnit[] expectedStream = new ByteStreamNALUnit[inputStream1.length + 3];
+ for (int i = 0; i < inputStream1.length; i++) {
+ expectedStream[index++] = inputStream1[i];
+ }
+ expectedStream[index++] = SAMPLE_STREAM[34];
+ expectedStream[index++] = SAMPLE_STREAM[35];
+ expectedStream[index] = SAMPLE_STREAM[36];
+
+ StreamVerifier verifier = new StreamVerifier(expectedStream);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp encoder = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ encoder.inputByteStreamWithArray(inputStream1);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.pause();
+
+ // this input stream should be disposed
+ encoder.inputByteStreamWithArray(inputStream2);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.resume();
+
+ // packetizer should resume from a I frame
+ encoder.inputByteStreamWithArray(inputStream3);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(expectedStream.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#sendFrame(byte[], int, int, long)}
+ */
+ public void testSendFrameInterfaceWithArray() {
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithArrayOffset(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#sendFrame(ByteBuffer, long)}
+ */
+ public void testSendFrameInterfaceWithByteBuffer() {
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithByteBuffer(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.RTPH264Packetizer#sendFrame(ByteBuffer, long)}
+ * with direct ByteBuffer
+ */
+ public void testSendFrameInterfaceWithDirectByteBuffer() {
+ StreamVerifier verifier = new StreamVerifier(SAMPLE_STREAM);
+ SdlSession session = createTestSession();
+ RTPH264Packetizer packetizer = null;
+ try {
+ packetizer = new RTPH264Packetizer(verifier, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithDirectByteBuffer(SAMPLE_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertEquals(SAMPLE_STREAM.length, verifier.getPacketCount());
+ }
+
+ private SdlSession createTestSession() {
+ return SdlSession.createSession(WIPRO_VERSION, new MockInterfaceBroker(), new BTTransportConfig(true));
+ }
+
+ private class StreamVerifier implements IStreamListener {
+ private static final int STATE_LENGTH = 0;
+ private static final int STATE_PACKET = 1;
+
+ private ByteStreamNALUnit[] mStream;
+ private byte[] mExpectedNALUnit;
+ private ByteBuffer mReceiveBuffer;
+ private int mPacketLen;
+ private int mState;
+ private int mNALCount;
+ private int mTotalPacketCount;
+ private boolean mFragmented;
+ private int mOffsetInNALUnit;
+ private byte mPayloadType;
+ private boolean mVerifySSRC;
+ private int mExpectedSSRC;
+ private boolean mFirstPacketReceived;
+ private short mFirstSequenceNum;
+ private int mFirstTimestamp;
+
+ StreamVerifier(ByteStreamNALUnit[] stream) {
+ this(stream, (byte)96);
+ }
+
+ StreamVerifier(ByteStreamNALUnit[] stream, byte payloadType) {
+ mStream = stream;
+ mReceiveBuffer = ByteBuffer.allocate(256 * 1024);
+ mReceiveBuffer.order(ByteOrder.BIG_ENDIAN);
+ mPacketLen = 0;
+ mState = STATE_LENGTH;
+
+ mNALCount = 0;
+ mTotalPacketCount = 0;
+ mFragmented = false;
+ mOffsetInNALUnit = 1; // Used when verifying FUs. The first byte is skipped.
+
+ mPayloadType = payloadType;
+ mVerifySSRC = false;
+ mExpectedSSRC = 0;
+ mFirstPacketReceived = false;
+ mFirstSequenceNum = 0;
+ mFirstTimestamp = 0;
+ }
+
+ void setExpectedSSRC(int ssrc) {
+ mVerifySSRC = true;
+ mExpectedSSRC = ssrc;
+ }
+
+ int getPacketCount() {
+ return mTotalPacketCount;
+ }
+
+ @Override
+ public void sendStreamPacket(ProtocolMessage pm) {
+ mExpectedNALUnit = mStream[mNALCount].nalUnit;
+ // should be same as MockVideoApp's configuration (29.97 FPS)
+ int expectedPTSDelta = mStream[mNALCount].frameNum * 1001 * 3;
+ boolean isLast = shouldBeLast();
+
+ verifyProtocolMessage(pm, SESSION_ID);
+
+ mReceiveBuffer.put(pm.getData());
+ mReceiveBuffer.flip();
+
+ if (mState == STATE_LENGTH) {
+ if (mReceiveBuffer.remaining() >= 2) {
+ mPacketLen = mReceiveBuffer.getShort() & 0xFFFF;
+ mState = STATE_PACKET;
+ }
+ }
+
+ if (mState == STATE_PACKET) {
+ if (mReceiveBuffer.remaining() >= mPacketLen) {
+ byte[] packet = new byte[mPacketLen];
+ mReceiveBuffer.get(packet);
+
+ verifyRTPPacket(packet, mPayloadType, expectedPTSDelta,
+ mVerifySSRC, mExpectedSSRC, isLast);
+ mFirstPacketReceived = true;
+
+ mState = STATE_LENGTH;
+ mPacketLen = 0;
+ mTotalPacketCount++;
+ }
+ }
+
+ mReceiveBuffer.compact();
+ }
+
+ private void verifyProtocolMessage(ProtocolMessage pm, byte sessionId) {
+ assertEquals(true, pm != null);
+ assertEquals(sessionId, pm.getSessionID());
+ assertEquals(SessionType.NAV, pm.getSessionType());
+ assertEquals(0, pm.getFunctionID());
+ assertEquals(0, pm.getCorrID());
+ assertEquals(false, pm.getPayloadProtected());
+ }
+
+ private void verifyRTPPacket(byte[] packet, byte payloadType, int expectedPTSDelta,
+ boolean verifySSRC, int expectedSSRC, boolean isLast) {
+ assertTrue(packet.length > RTP_HEADER_LEN);
+ verifyRTPHeader(packet, false, isLast, payloadType, (short)(mTotalPacketCount % 65536),
+ expectedPTSDelta, verifySSRC, expectedSSRC);
+
+ byte type = (byte)(packet[RTP_HEADER_LEN] & 0x1F);
+ if (type == 28) { // FU-A frame
+ boolean fuEnd = verifyFUTypeA(packet);
+ if (fuEnd) {
+ mNALCount++;
+ }
+ } else if (type == 29) { // FU-B frame
+ fail("Fragmentation Unit B is not supported by this test");
+ } else if (type == 24 || type == 25 || type == 26 || type == 27) {
+ fail("STAP and MTAP are not supported by this test");
+ } else {
+ // Single Frame
+ verifySingleFrame(packet);
+ mNALCount++;
+ }
+ }
+
+ private void verifyRTPHeader(byte[] packet,
+ boolean hasPadding, boolean isLast, byte payloadType,
+ short seqNumDelta, int ptsDelta, boolean checkSSRC, int ssrc) {
+ int byte0 = packet[0] & 0xFF;
+ assertEquals((byte)2, (byte)((byte0 >> 6) & 3)); // version
+ assertEquals((byte)(hasPadding ? 1 : 0), (byte)((byte0 >> 5) & 1)); // padding
+ assertEquals((byte)0, (byte)((byte0 >> 4) & 1)); // extension
+ assertEquals((byte)0, (byte)(byte0 & 0xF)); // CSRC count
+
+ int byte1 = packet[1] & 0xFF;
+ assertEquals((byte)(isLast ? 1 : 0), (byte)((byte1 >> 7) & 1)); // marker
+ assertEquals(payloadType, (byte)(byte1 & 0x7F)); // Payload Type
+
+ short actualSeq = (short)(((packet[2] & 0xFF) << 8) | (packet[3] & 0xFF));
+ if (!mFirstPacketReceived) {
+ mFirstSequenceNum = actualSeq;
+ } else {
+ assertEquals((short)(mFirstSequenceNum + seqNumDelta), actualSeq);
+ }
+
+ int actualPTS = ((packet[4] & 0xFF) << 24) | ((packet[5] & 0xFF) << 16) |
+ ((packet[6] & 0xFF) << 8) | (packet[7] & 0xFF);
+ if (!mFirstPacketReceived) {
+ mFirstTimestamp = actualPTS;
+ } else {
+ // accept calculation error
+ assertTrue(mFirstTimestamp + ptsDelta - 1 <= actualPTS &&
+ actualPTS <= mFirstTimestamp + ptsDelta + 1);
+ }
+
+ if (checkSSRC) {
+ int actualSSRC = ((packet[8] & 0xFF) << 24) | ((packet[9] & 0xFF) << 16) |
+ ((packet[10] & 0xFF) << 8) | (packet[11] & 0xFF);
+ assertEquals(ssrc, actualSSRC);
+ }
+ }
+
+ private void verifySingleFrame(byte[] packet) {
+ assertEquals(true, arrayCompare(packet, RTP_HEADER_LEN, packet.length - RTP_HEADER_LEN,
+ mExpectedNALUnit, 0, mExpectedNALUnit.length));
+ }
+
+ private boolean verifyFUTypeA(byte[] packet) {
+ int firstByte = mExpectedNALUnit[0] & 0xFF;
+
+ int byte0 = packet[RTP_HEADER_LEN] & 0xFF;
+ assertEquals((byte)((firstByte >> 7) & 1), (byte)((byte0 >> 7) & 1)); // F bit
+ assertEquals((byte)((firstByte >> 5) & 3), (byte)((byte0 >> 5) & 3)); // NRI
+ assertEquals((byte)28, (byte)(byte0 & 0x1F)); // Type
+
+ int byte1 = packet[RTP_HEADER_LEN+1] & 0xFF;
+ boolean isFirstFU = ((byte1 >> 7) & 1) == 1; // Start bit
+ boolean isLastFU = ((byte1 >> 6) & 1) == 1; // End bit
+ assertEquals((byte)0, (byte)((byte1 >> 5) & 1)); // Reserved bit
+ assertEquals((byte)(firstByte & 0x1F), (byte)(byte1 & 0x1F)); // Type
+
+ int len = packet.length - (RTP_HEADER_LEN + 2);
+ assertEquals(true, arrayCompare(packet, RTP_HEADER_LEN + 2, len, mExpectedNALUnit, mOffsetInNALUnit, len));
+ mOffsetInNALUnit += len;
+
+ if (!mFragmented) {
+ // this should be the first fragmentation unit
+ assertEquals(true, isFirstFU);
+ assertEquals(false, isLastFU);
+ mFragmented = true;
+ } else {
+ assertEquals(false, isFirstFU);
+ if (mExpectedNALUnit.length == mOffsetInNALUnit) {
+ // this is the last fragmentation unit
+ assertEquals(true, isLastFU);
+
+ mFragmented = false;
+ mOffsetInNALUnit = 1;
+ return true;
+ } else {
+ assertEquals(false, isLastFU);
+ }
+ }
+ return false;
+ }
+
+ private boolean shouldBeLast() {
+ if (mNALCount + 1 >= mStream.length) {
+ return true;
+ }
+ ByteStreamNALUnit current = mStream[mNALCount];
+ ByteStreamNALUnit next = mStream[mNALCount + 1];
+ if (next.frameNum != current.frameNum) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean arrayCompare(byte[] a1, int start1, int len1, byte[] a2, int start2, int len2) {
+ assertTrue(start1 + len1 <= a1.length);
+ assertTrue(start2 + len2 <= a2.length);
+
+ if (len1 != len2) {
+ return false;
+ }
+
+ for (int i = 0; i < len1; i++) {
+ if (a1[start1 + i] != a2[start2 + i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private interface IVideoFrameSender {
+ void onVideoFrame(byte[] data, long timestampUs);
+ }
+
+ private class MockVideoApp {
+ private IVideoStreamListener mListener;
+ private int mFPSNum;
+ private int mFPSDen;
+
+ MockVideoApp(IVideoStreamListener listener) {
+ mListener = listener;
+ // 29.97 fps
+ mFPSNum = 30000;
+ mFPSDen = 1001;
+ }
+
+ void inputByteStreamWithArray(ByteStreamNALUnit[] stream) {
+ generateFramesFromStream(stream, new IVideoFrameSender() {
+ @Override
+ public void onVideoFrame(byte[] data, long timestampUs) {
+ byte[] buffer = new byte[data.length];
+ System.arraycopy(data, 0, buffer, 0, data.length);
+ mListener.sendFrame(buffer, 0, data.length, timestampUs);
+ }
+ });
+ }
+
+ void inputByteStreamWithArrayOffset(ByteStreamNALUnit[] stream) {
+ generateFramesFromStream(stream, new IVideoFrameSender() {
+ private int mDummyOffset = 0;
+
+ @Override
+ public void onVideoFrame(byte[] data, long timestampUs) {
+ // to test 'offset' param, create a buffer with a dummy offset
+ byte[] buffer = new byte[mDummyOffset + data.length];
+ System.arraycopy(data, 0, buffer, mDummyOffset, data.length);
+
+ mListener.sendFrame(buffer, mDummyOffset, data.length, timestampUs);
+ mDummyOffset++;
+ }
+ });
+ }
+
+ void inputByteStreamWithByteBuffer(ByteStreamNALUnit[] stream) {
+ generateFramesFromStream(stream, new IVideoFrameSender() {
+ private int mDummyOffset = 0;
+
+ @Override
+ public void onVideoFrame(byte[] data, long timestampUs) {
+ // add a dummy offset inside byteBuffer for testing
+ ByteBuffer byteBuffer = ByteBuffer.allocate(mDummyOffset + data.length);
+ byteBuffer.position(mDummyOffset);
+
+ byteBuffer.put(data);
+ byteBuffer.flip();
+ byteBuffer.position(mDummyOffset);
+
+ mListener.sendFrame(byteBuffer, timestampUs);
+ mDummyOffset++;
+ }
+ });
+ }
+
+ void inputByteStreamWithDirectByteBuffer(ByteStreamNALUnit[] stream) {
+ generateFramesFromStream(stream, new IVideoFrameSender() {
+ private int mDummyOffset = 0;
+
+ @Override
+ public void onVideoFrame(byte[] data, long timestampUs) {
+ // add a dummy offset inside byteBuffer for testing
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(mDummyOffset + data.length);
+ byteBuffer.position(mDummyOffset);
+
+ byteBuffer.put(data);
+ byteBuffer.flip();
+ byteBuffer.position(mDummyOffset);
+
+ mListener.sendFrame(byteBuffer, timestampUs);
+ mDummyOffset++;
+ }
+ });
+ }
+
+ private void generateFramesFromStream(ByteStreamNALUnit[] stream, IVideoFrameSender callback) {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ for (int i = 0; i < stream.length; i++) {
+ ByteStreamNALUnit bs = stream[i];
+ byte[] array = bs.createArray();
+ os.write(array, 0, array.length);
+
+ if (i < stream.length - 1) {
+ ByteStreamNALUnit next = stream[i + 1];
+ if (bs.frameNum == next.frameNum) {
+ // enqueue it and send at once
+ continue;
+ }
+ }
+
+ long timestampUs = bs.frameNum * 1000L * 1000L * mFPSDen / mFPSNum;
+ byte[] data = os.toByteArray();
+ callback.onVideoFrame(data, timestampUs);
+ os.reset();
+ }
+
+ try {
+ os.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+}
diff --git a/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/StreamPacketizerTests.java b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/StreamPacketizerTests.java
index 218e904b3..5f5bd6d2b 100644
--- a/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/StreamPacketizerTests.java
+++ b/sdl_android/src/androidTest/java/com/smartdevicelink/test/streaming/StreamPacketizerTests.java
@@ -2,13 +2,18 @@ package com.smartdevicelink.test.streaming;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
import com.smartdevicelink.SdlConnection.SdlSession;
+import com.smartdevicelink.protocol.ProtocolMessage;
import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
import com.smartdevicelink.streaming.IStreamListener;
import com.smartdevicelink.streaming.StreamPacketizer;
import com.smartdevicelink.test.Test;
@@ -22,7 +27,96 @@ import junit.framework.TestCase;
* {@link com.smartdevicelink.streaming.StreamPacketizer}
*/
public class StreamPacketizerTests extends TestCase {
-
+
+ private static final byte WIPRO_VERSION = 0x0B;
+ private static final byte SESSION_ID = 0x0A;
+
+ private final byte[][] SAMPLE_H264_VIDEO_STREAM = {
+ // one byte array represents a frame
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20,
+ 0x00, 0x00, 0x01,
+ 0x65, (byte)0x88, (byte)0x82, 0x07, 0x67, 0x39, 0x31, 0x40,
+ 0x00, 0x5E, 0x0A, (byte)0xFB, (byte)0xEF, (byte)0xAE, (byte)0xBA, (byte)0xEB,
+ (byte)0xAE, (byte)0xBA, (byte)0xEB, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x1C, 0x0E, (byte)0xCE, 0x71, (byte)0xB0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x2A, 0x03, (byte)0xB3, (byte)0x9C, 0x6C},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x3B, 0x03, (byte)0xB3, (byte)0x9C, 0x6C},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x49, 0x00, (byte)0xEC, (byte)0xE7, 0x1B},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x59, 0x40, (byte)0xEC, (byte)0xE7, 0x1B},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x69, (byte)0x80, (byte)0xEC, (byte)0xE7, 0x1B},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x79, (byte)0xC0, (byte)0xEC, (byte)0xE7, 0x1B},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0x88, (byte)0x80, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0x98, (byte)0x90, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xA8, (byte)0xA0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xB8, (byte)0xB0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xC8, (byte)0xC0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xD8, (byte)0xD0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xE8, (byte)0xE0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, (byte)0xF8, (byte)0xF0, 0x3B, 0x39, (byte)0xC6, (byte)0xC0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x00, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x10, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x20, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x30, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x40, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x50, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x60, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, 0x70, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0x80, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0x90, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0xA0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0xB0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0xC0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9B, (byte)0xD0, 0x1D, (byte)0x9C, (byte)0xE3, 0x60},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x67, 0x42, (byte)0xC0, 0x0A, (byte)0xA6, 0x11, 0x11, (byte)0xE8,
+ 0x40, 0x00, 0x00, (byte)0xFA, 0x40, 0x00, 0x3A, (byte)0x98,
+ 0x23, (byte)0xC4, (byte)0x89, (byte)0x84, 0x60,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x68, (byte)0xC8, 0x42, 0x0F, 0x13, 0x20,
+ 0x00, 0x00, 0x01,
+ 0x65, (byte)0x88, (byte)0x81, 0x00, (byte)0x8E, 0x73, (byte)0x93, 0x14,
+ 0x00, 0x06, (byte)0xA4, 0x2F, (byte)0xBE, (byte)0xFA, (byte)0xEB, (byte)0xAE,
+ (byte)0xBA, (byte)0xEB, (byte)0xAE, (byte)0xBC},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x1C, 0x0D, (byte)0xCE, 0x71, (byte)0xB0},
+ new byte[]{0x00, 0x00, 0x00, 0x01,
+ 0x41, (byte)0x9A, 0x2A, 0x03, 0x33, (byte)0x9C, 0x6C},
+ };
+
/**
* This is a unit test for the following methods :
* {@link com.smartdevicelink.streaming.StreamPacketizer#StreamPacketizer(IStreamListener, InputStream, SessionType, byte)}
@@ -49,4 +143,369 @@ public class StreamPacketizerTests extends TestCase {
fail("IOException was thrown.");
}
}
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendFrame(byte[], int, int, long)}
+ */
+ public void testSendFrameInterfaceWithArray() {
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithArray(SAMPLE_H264_VIDEO_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(SAMPLE_H264_VIDEO_STREAM));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendFrame(byte[], int, int, long)}
+ * with offset parameter
+ */
+ public void testSendFrameInterfaceWithArrayOffset() {
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithArrayOffset(SAMPLE_H264_VIDEO_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(SAMPLE_H264_VIDEO_STREAM));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendFrame(ByteBuffer, long)}
+ */
+ public void testSendFrameInterfaceWithByteBuffer() {
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithByteBuffer(SAMPLE_H264_VIDEO_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(SAMPLE_H264_VIDEO_STREAM));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendFrame(ByteBuffer, long)}
+ * with direct ByteBuffer
+ */
+ public void testSendFrameInterfaceWithDirectByteBuffer() {
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithDirectByteBuffer(SAMPLE_H264_VIDEO_STREAM);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(SAMPLE_H264_VIDEO_STREAM));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendAudio(byte[], int, int, long)}
+ */
+ public void testSendAudioInterfaceWithArray() {
+ // assume 100 data of 16kHz / 16bits audio for 10 msecs
+ int dataCount = 100;
+ byte[][] sampleAudio = new byte[dataCount][];
+ for (int i = 0; i < dataCount; i++) {
+ sampleAudio[i] = new byte[4 * 160];
+ Arrays.fill(sampleAudio[i], (byte)0);
+ }
+
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithArray(sampleAudio);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(sampleAudio));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendAudio(byte[], int, int, long)}
+ */
+ public void testSendAudioInterfaceWithArrayOffset() {
+ // assume 100 data of 16kHz / 16bits audio for 10 msecs
+ int dataCount = 100;
+ byte[][] sampleAudio = new byte[dataCount][];
+ for (int i = 0; i < dataCount; i++) {
+ sampleAudio[i] = new byte[4 * 160];
+ Arrays.fill(sampleAudio[i], (byte)0);
+ }
+
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithArrayOffset(sampleAudio);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(sampleAudio));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendAudio(ByteBuffer, long)}
+ */
+ public void testSendAudioInterfaceWithByteBuffer() {
+ // assume 100 data of 16kHz / 16bits audio for 10 msecs
+ int dataCount = 100;
+ byte[][] sampleAudio = new byte[dataCount][];
+ for (int i = 0; i < dataCount; i++) {
+ sampleAudio[i] = new byte[4 * 160];
+ Arrays.fill(sampleAudio[i], (byte)0);
+ }
+
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithByteBuffer(sampleAudio);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(sampleAudio));
+ }
+
+ /**
+ * Test for {@link com.smartdevicelink.streaming.StreamPacketizer#sendAudio(ByteBuffer, long)}
+ * with direct ByteBuffer
+ */
+ public void testSendAudioInterfaceWithDirectByteBuffer() {
+ // assume 100 data of 16kHz / 16bits audio for 10 msecs
+ int dataCount = 100;
+ byte[][] sampleAudio = new byte[dataCount][];
+ for (int i = 0; i < dataCount; i++) {
+ sampleAudio[i] = new byte[4 * 160];
+ Arrays.fill(sampleAudio[i], (byte)0);
+ }
+
+ StreamReceiver mockReceiver = new StreamReceiver();
+ SdlSession session = createTestSession();
+ StreamPacketizer packetizer = null;
+ try {
+ packetizer = new StreamPacketizer(mockReceiver, null, SessionType.NAV, SESSION_ID, session);
+ } catch (IOException e) {
+ fail();
+ }
+ MockVideoApp mockApp = new MockVideoApp(packetizer);
+
+ try {
+ packetizer.start();
+ } catch (IOException e) {
+ fail();
+ }
+
+ mockApp.inputByteStreamWithDirectByteBuffer(sampleAudio);
+ try {
+ Thread.sleep(1000, 0);
+ } catch (InterruptedException e) {}
+
+ packetizer.stop();
+ assertTrue(mockReceiver.verify(sampleAudio));
+ }
+
+
+ private SdlSession createTestSession() {
+ return SdlSession.createSession(WIPRO_VERSION, new MockInterfaceBroker(), new BTTransportConfig(true));
+ }
+
+ private class StreamReceiver implements IStreamListener {
+ private ByteArrayOutputStream mReceiveBuffer;
+
+ StreamReceiver() {
+ mReceiveBuffer = new ByteArrayOutputStream();
+ }
+
+ @Override
+ public void sendStreamPacket(ProtocolMessage pm) {
+ try {
+ mReceiveBuffer.write(pm.getData());
+ } catch (IOException e) {
+ fail();
+ }
+ }
+
+ boolean verify(byte[][] expectedStream) {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ for (byte[] frame : expectedStream) {
+ try {
+ buffer.write(frame);
+ } catch (IOException e) {
+ fail();
+ }
+ }
+ boolean result = Arrays.equals(buffer.toByteArray(), mReceiveBuffer.toByteArray());
+ try {
+ buffer.close();
+ } catch (IOException e) {
+ fail();
+ }
+ return result;
+ }
+ }
+
+ private class MockVideoApp {
+ private IVideoStreamListener mListener;
+
+ MockVideoApp(IVideoStreamListener listener) {
+ mListener = listener;
+ }
+
+ void inputByteStreamWithArray(byte[][] stream) {
+ for (byte[] data : stream) {
+ mListener.sendFrame(data, 0, data.length, -1);
+ }
+ }
+
+ void inputByteStreamWithArrayOffset(byte[][] stream) {
+ int dummyOffset = 0;
+ for (byte[] data : stream) {
+ // to test 'offset' param, create a buffer with a dummy offset
+ byte[] buffer = new byte[dummyOffset + data.length];
+ System.arraycopy(data, 0, buffer, dummyOffset, data.length);
+
+ mListener.sendFrame(buffer, dummyOffset, data.length, -1);
+ dummyOffset++;
+ }
+ }
+
+ void inputByteStreamWithByteBuffer(byte[][] stream) {
+ int dummyOffset = 0;
+ for (byte[] data : stream) {
+ // add a dummy offset inside byteBuffer for testing
+ ByteBuffer byteBuffer = ByteBuffer.allocate(dummyOffset + data.length);
+ byteBuffer.position(dummyOffset);
+
+ byteBuffer.put(data);
+ byteBuffer.flip();
+ byteBuffer.position(dummyOffset);
+
+ mListener.sendFrame(byteBuffer, -1);
+ dummyOffset++;
+ }
+ }
+
+ void inputByteStreamWithDirectByteBuffer(byte[][] stream) {
+ int dummyOffset = 0;
+ for (byte[] data : stream) {
+ // add a dummy offset inside byteBuffer for testing
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(dummyOffset + data.length);
+ byteBuffer.position(dummyOffset);
+
+ byteBuffer.put(data);
+ byteBuffer.flip();
+ byteBuffer.position(dummyOffset);
+
+ mListener.sendFrame(byteBuffer, -1);
+ dummyOffset++;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
index f4b4c43d9..16350da4b 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/ISdlConnectionListener.java
@@ -3,6 +3,8 @@ package com.smartdevicelink.SdlConnection;
import com.smartdevicelink.protocol.ProtocolMessage;
import com.smartdevicelink.protocol.enums.SessionType;
+import java.util.List;
+
public interface ISdlConnectionListener {
public void onTransportDisconnected(String info);
@@ -12,7 +14,7 @@ public interface ISdlConnectionListener {
public void onProtocolMessageReceived(ProtocolMessage msg);
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID);
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams);
public void onProtocolSessionStarted(SessionType sessionType,
byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted);
diff --git a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java
index 272c1878d..b346884aa 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java
@@ -1,6 +1,7 @@
package com.smartdevicelink.SdlConnection;
+import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import android.content.ComponentName;
@@ -263,8 +264,9 @@ public class SdlConnection implements IProtocolListener, ITransportListener {
@Override
public void onProtocolSessionNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
- _connectionListener.onProtocolSessionStartedNACKed(sessionType, sessionID, version, correlationID);
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
+ _connectionListener.onProtocolSessionStartedNACKed(sessionType,
+ sessionID, version, correlationID, rejectedParams);
}
@Override
@@ -433,10 +435,11 @@ public class SdlConnection implements IProtocolListener, ITransportListener {
@Override
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
SdlSession session = findSessionById(sessionID);
if (session != null) {
- session.onProtocolSessionStartedNACKed(sessionType, sessionID, version, correlationID);
+ session.onProtocolSessionStartedNACKed(sessionType,
+ sessionID, version, correlationID, rejectedParams);
}
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java
index 23521f4bb..f4a9fb97f 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java
@@ -23,10 +23,16 @@ import com.smartdevicelink.protocol.heartbeat.IHeartbeatMonitor;
import com.smartdevicelink.protocol.heartbeat.IHeartbeatMonitorListener;
import com.smartdevicelink.proxy.LockScreenManager;
import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
+import com.smartdevicelink.proxy.rpc.VideoStreamingFormat;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingProtocol;
import com.smartdevicelink.security.ISecurityInitializedListener;
import com.smartdevicelink.security.SdlSecurityBase;
+import com.smartdevicelink.streaming.AbstractPacketizer;
import com.smartdevicelink.streaming.IStreamListener;
+import com.smartdevicelink.streaming.RTPH264Packetizer;
import com.smartdevicelink.streaming.StreamPacketizer;
import com.smartdevicelink.streaming.StreamRPCPacketizer;
import com.smartdevicelink.streaming.VideoStreamingParameters;
@@ -49,7 +55,7 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
private LockScreenManager lockScreenMan = new LockScreenManager();
private SdlSecurityBase sdlSecurity = null;
StreamRPCPacketizer mRPCPacketizer = null;
- StreamPacketizer mVideoPacketizer = null;
+ AbstractPacketizer mVideoPacketizer = null;
StreamPacketizer mAudioPacketizer = null;
SdlEncoder mSdlEncoder = null;
private final static int BUFF_READ_SIZE = 1024;
@@ -119,6 +125,14 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
}
}
+ public long getMtu(SessionType type) {
+ if (this._sdlConnection != null) {
+ return this._sdlConnection.getWiProProtocol().getMtu(type);
+ } else {
+ return 0;
+ }
+ }
+
public void close() {
if (sdlSecurity != null)
{
@@ -140,8 +154,10 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
public void startStream(InputStream is, SessionType sType, byte rpcSessionID) throws IOException {
if (sType.equals(SessionType.NAV))
{
- mVideoPacketizer = new StreamPacketizer(this, is, sType, rpcSessionID, this);
- mVideoPacketizer.sdlConnection = this.getSdlConnection();
+ // protocol is fixed to RAW
+ StreamPacketizer packetizer = new StreamPacketizer(this, is, sType, rpcSessionID, this);
+ packetizer.sdlConnection = this.getSdlConnection();
+ mVideoPacketizer = packetizer;
mVideoPacketizer.start();
}
else if (sType.equals(SessionType.PCM))
@@ -163,8 +179,10 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
}
if (sType.equals(SessionType.NAV))
{
- mVideoPacketizer = new StreamPacketizer(this, is, sType, rpcSessionID, this);
- mVideoPacketizer.sdlConnection = this.getSdlConnection();
+ // protocol is fixed to RAW
+ StreamPacketizer packetizer = new StreamPacketizer(this, is, sType, rpcSessionID, this);
+ packetizer.sdlConnection = this.getSdlConnection();
+ mVideoPacketizer = packetizer;
mVideoPacketizer.start();
}
else if (sType.equals(SessionType.PCM))
@@ -181,7 +199,47 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
}
return os;
}
-
+
+ public IVideoStreamListener startVideoStream() {
+ byte rpcSessionID = getSessionId();
+ VideoStreamingProtocol protocol = getAcceptedProtocol();
+ try {
+ switch (protocol) {
+ case RAW: {
+ StreamPacketizer packetizer = new StreamPacketizer(this, null, SessionType.NAV, rpcSessionID, this);
+ packetizer.sdlConnection = this.getSdlConnection();
+ mVideoPacketizer = packetizer;
+ mVideoPacketizer.start();
+ return packetizer;
+ }
+ case RTP: {
+ RTPH264Packetizer packetizer = new RTPH264Packetizer(this, SessionType.NAV, rpcSessionID, this);
+ mVideoPacketizer = packetizer;
+ mVideoPacketizer.start();
+ return packetizer;
+ }
+ default:
+ Log.e(TAG, "Protocol " + protocol + " is not supported.");
+ return null;
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ public IAudioStreamListener startAudioStream() {
+ byte rpcSessionID = getSessionId();
+ try {
+ StreamPacketizer packetizer = new StreamPacketizer(this, null, SessionType.PCM, rpcSessionID, this);
+ packetizer.sdlConnection = this.getSdlConnection();
+ mAudioPacketizer = packetizer;
+ mAudioPacketizer.start();
+ return packetizer;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
public void startRPCStream(InputStream is, RPCRequest request, SessionType sType, byte rpcSessionID, byte wiproVersion) {
try {
mRPCPacketizer = new StreamRPCPacketizer(null, this, is, request, sType, rpcSessionID, wiproVersion, 0, this);
@@ -290,19 +348,18 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
public Surface createOpenGLInputSurface(int frameRate, int iFrameInterval, int width,
int height, int bitrate, SessionType sType, byte rpcSessionID) {
- try {
- PipedOutputStream stream = (PipedOutputStream) startStream(sType, rpcSessionID);
- if (stream == null) return null;
- mSdlEncoder = new SdlEncoder();
- mSdlEncoder.setFrameRate(frameRate);
- mSdlEncoder.setFrameInterval(iFrameInterval);
- mSdlEncoder.setFrameWidth(width);
- mSdlEncoder.setFrameHeight(height);
- mSdlEncoder.setBitrate(bitrate);
- mSdlEncoder.setOutputStream(stream);
- } catch (IOException e) {
+ IVideoStreamListener encoderListener = startVideoStream();
+ if (encoderListener == null) {
return null;
}
+
+ mSdlEncoder = new SdlEncoder();
+ mSdlEncoder.setFrameRate(frameRate);
+ mSdlEncoder.setFrameInterval(iFrameInterval);
+ mSdlEncoder.setFrameWidth(width);
+ mSdlEncoder.setFrameHeight(height);
+ mSdlEncoder.setBitrate(bitrate);
+ mSdlEncoder.setOutputListener(encoderListener);
return mSdlEncoder.prepareEncoder();
}
@@ -551,8 +608,9 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
@Override
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
- this.sessionListener.onProtocolSessionStartedNACKed(sessionType, sessionID, version, correlationID);
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
+ this.sessionListener.onProtocolSessionStartedNACKed(sessionType,
+ sessionID, version, correlationID, rejectedParams);
if(serviceListeners != null && serviceListeners.containsKey(sessionType)){
CopyOnWriteArrayList<ISdlServiceListener> listeners = serviceListeners.get(sessionType);
for(ISdlServiceListener listener:listeners){
@@ -673,4 +731,18 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList
public VideoStreamingParameters getAcceptedVideoParams(){
return acceptedVideoParams;
}
+
+ private VideoStreamingProtocol getAcceptedProtocol() {
+ // acquire default protocol (RAW)
+ VideoStreamingProtocol protocol = new VideoStreamingParameters().getFormat().getProtocol();
+
+ if (acceptedVideoParams != null) {
+ VideoStreamingFormat format = acceptedVideoParams.getFormat();
+ if (format != null && format.getProtocol() != null) {
+ protocol = format.getProtocol();
+ }
+ }
+
+ return protocol;
+ }
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java b/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java
new file mode 100644
index 000000000..362564da8
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.encoder;
+
+import android.annotation.TargetApi;
+import android.media.MediaFormat;
+import android.os.Build;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public final class EncoderUtils {
+ private final static String TAG = "EncoderUtils";
+
+ /**
+ * Extracts codec-specific data from MediaFormat instance
+ *
+ * Currently, only AVC is supported.
+ *
+ * @param format MediaFormat instance retrieved from MediaCodec
+ * @return byte array containing codec-specific data, or null if an error occurred
+ */
+ public static byte[] getCodecSpecificData(MediaFormat format) {
+ if (format == null) {
+ return null;
+ }
+
+ String name = format.getString(MediaFormat.KEY_MIME);
+ if (name == null) {
+ return null;
+ }
+
+ // same as MediaFormat.MIMETYPE_VIDEO_AVC but it requires API level 21
+ if (name.equals("video/avc")) {
+ return getAVCCodecSpecificData(format);
+ } else {
+ Log.w(TAG, "Retrieving codec-specific data for " + name + " is not supported");
+ return null;
+ }
+ }
+
+ /**
+ * Extracts H.264 codec-specific data (SPS and PPS) from MediaFormat instance
+ *
+ * The codec-specific data is in byte-stream format; 4-byte start codes (0x00 0x00 0x00 0x01)
+ * are added in front of SPS and PPS NAL units.
+ *
+ * @param format MediaFormat instance retrieved from MediaCodec
+ * @return byte array containing codec-specific data, or null if an error occurred
+ */
+ private static byte[] getAVCCodecSpecificData(MediaFormat format) {
+ // For H.264, "csd-0" contains SPS and "csd-1" contains PPS. Refer to the documentation
+ // of MediaCodec.
+ if (!(format.containsKey("csd-0") && format.containsKey("csd-1"))) {
+ Log.w(TAG, "H264 codec specific data not found");
+ return null;
+ }
+
+ ByteBuffer sps = format.getByteBuffer("csd-0");
+ int spsLen = sps.remaining();
+ ByteBuffer pps = format.getByteBuffer("csd-1");
+ int ppsLen = pps.remaining();
+
+ byte[] output = new byte[spsLen + ppsLen];
+ try {
+ sps.get(output, 0, spsLen);
+ pps.get(output, spsLen, ppsLen);
+ } catch (Exception e) {
+ // should not happen
+ Log.w(TAG, "Error while copying H264 codec specific data: " + e);
+ return null;
+ }
+
+ return output;
+ }
+
+ private EncoderUtils() {}
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java b/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java
index 81e344840..196f5d98c 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java
@@ -9,11 +9,16 @@ import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Build;
+import android.util.Log;
import android.view.Surface;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
+
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class SdlEncoder {
-
+
+ private static final String TAG = "SdlEncoder";
+
// parameters for the encoder
private static final String _MIME_TYPE = "video/avc"; // H.264/AVC video
// private static final String MIME_TYPE = "video/mp4v-es"; //MPEG4 video
@@ -26,10 +31,13 @@ public class SdlEncoder {
// encoder state
private MediaCodec mEncoder;
private PipedOutputStream mOutputStream;
+ private IVideoStreamListener mOutputListener;
// allocate one of these up front so we don't need to do it every time
private MediaCodec.BufferInfo mBufferInfo;
-
+
+ // Codec-specific data (SPS and PPS)
+ private byte[] mH264CodecSpecificData = null;
public SdlEncoder () {
}
@@ -51,6 +59,9 @@ public class SdlEncoder {
public void setOutputStream(PipedOutputStream mStream){
mOutputStream = mStream;
}
+ public void setOutputListener(IVideoStreamListener listener) {
+ mOutputListener = listener;
+ }
public Surface prepareEncoder () {
mBufferInfo = new MediaCodec.BufferInfo();
@@ -114,6 +125,7 @@ public class SdlEncoder {
}
mOutputStream = null;
}
+ mH264CodecSpecificData = null;
}
/**
@@ -127,7 +139,7 @@ public class SdlEncoder {
public void drainEncoder(boolean endOfStream) {
final int TIMEOUT_USEC = 10000;
- if(mEncoder == null || mOutputStream == null) {
+ if(mEncoder == null || (mOutputStream == null && mOutputListener == null)) {
return;
}
if (endOfStream) {
@@ -147,15 +159,45 @@ public class SdlEncoder {
// not expected for an encoder
encoderOutputBuffers = mEncoder.getOutputBuffers();
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ if (mH264CodecSpecificData == null) {
+ MediaFormat format = mEncoder.getOutputFormat();
+ mH264CodecSpecificData = EncoderUtils.getCodecSpecificData(format);
+ } else {
+ Log.w(TAG, "Output format change notified more than once, ignoring.");
+ }
} else if (encoderStatus < 0) {
} else {
+ if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
+ // If we already retrieve codec specific data via OUTPUT_FORMAT_CHANGED event,
+ // we do not need this data.
+ if (mH264CodecSpecificData != null) {
+ mBufferInfo.size = 0;
+ } else {
+ Log.i(TAG, "H264 codec specific data not retrieved yet.");
+ }
+ }
+ // append SPS and PPS in front of every IDR NAL unit
+ if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0
+ && mBufferInfo.size != 0
+ && mH264CodecSpecificData != null) {
+ try {
+ mOutputStream.write(mH264CodecSpecificData, 0,
+ mH264CodecSpecificData.length);
+ } catch (Exception e) {}
+ }
+
if (mBufferInfo.size != 0) {
byte[] dataToWrite = new byte[mBufferInfo.size];
encoderOutputBuffers[encoderStatus].get(dataToWrite,
mBufferInfo.offset, mBufferInfo.size);
try {
- mOutputStream.write(dataToWrite, 0, mBufferInfo.size);
+ if (mOutputStream != null) {
+ mOutputStream.write(dataToWrite, 0, mBufferInfo.size);
+ } else if (mOutputListener != null) {
+ mOutputListener.sendFrame(
+ dataToWrite, 0, dataToWrite.length, mBufferInfo.presentationTimeUs);
+ }
} catch (Exception e) {}
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/protocol/AbstractProtocol.java b/sdl_android/src/main/java/com/smartdevicelink/protocol/AbstractProtocol.java
index 8acc709e1..bb8c7fb6c 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/protocol/AbstractProtocol.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/protocol/AbstractProtocol.java
@@ -3,6 +3,8 @@ package com.smartdevicelink.protocol;
import com.smartdevicelink.protocol.WiProProtocol.MessageFrameAssembler;
import com.smartdevicelink.protocol.enums.SessionType;
+import java.util.List;
+
public abstract class AbstractProtocol {
private static final String SDL_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66";
@@ -31,6 +33,7 @@ public abstract class AbstractProtocol {
public abstract void SendMessage(ProtocolMessage msg);
public abstract int getMtu();
+ public abstract long getMtu(SessionType type);
public abstract void handlePacketReceived(SdlPacket packet);
@@ -128,8 +131,8 @@ public abstract class AbstractProtocol {
}
protected void handleProtocolSessionNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
- _protocolListener.onProtocolSessionNACKed(sessionType, sessionID, version, correlationID);
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
+ _protocolListener.onProtocolSessionNACKed(sessionType, sessionID, version, correlationID, rejectedParams);
}
// This method handles protocol errors. A callback is sent to the protocol
diff --git a/sdl_android/src/main/java/com/smartdevicelink/protocol/IProtocolListener.java b/sdl_android/src/main/java/com/smartdevicelink/protocol/IProtocolListener.java
index b54ff66c8..04397b935 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/protocol/IProtocolListener.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/protocol/IProtocolListener.java
@@ -2,6 +2,8 @@ package com.smartdevicelink.protocol;
import com.smartdevicelink.protocol.enums.*;
+import java.util.List;
+
public interface IProtocolListener {
// Called to indicate that these bytes are to be sent as part of a message.
// This call includes the part of the message.
@@ -14,7 +16,8 @@ public interface IProtocolListener {
// Called to indicate that a protocol session has been started (from either side)
void onProtocolSessionStarted(SessionType sessionType, byte sessionID, byte version, String correlationID, int hashID, boolean isEncrypted);
- void onProtocolSessionNACKed(SessionType sessionType, byte sessionID, byte version, String correlationID);
+ void onProtocolSessionNACKed(SessionType sessionType, byte sessionID, byte version,
+ String correlationID, List<String> rejectedParams);
// Called to indicate that a protocol session has ended (from either side)
void onProtocolSessionEnded(SessionType sessionType, byte sessionID, String correlationID /*, String info, Exception ex*/);
diff --git a/sdl_android/src/main/java/com/smartdevicelink/protocol/ProtocolMessage.java b/sdl_android/src/main/java/com/smartdevicelink/protocol/ProtocolMessage.java
index 99b34aff6..cb5ad3a74 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/protocol/ProtocolMessage.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/protocol/ProtocolMessage.java
@@ -45,12 +45,16 @@ public class ProtocolMessage {
this._data = data;
this._jsonSize = data.length;
}
-
+
public void setData(byte[] data, int length) {
+ setData(data, 0, length);
+ }
+
+ public void setData(byte[] data, int offset, int length) {
if (this._data != null)
this._data = null;
this._data = new byte[length];
- System.arraycopy(data, 0, this._data, 0, length);
+ System.arraycopy(data, offset, this._data, 0, length);
this._jsonSize = 0;
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java b/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java
index b5aca82dc..d79dbe27f 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java
@@ -150,10 +150,17 @@ public class WiProProtocol extends AbstractProtocol {
} // end-method
public void EndProtocolSession(SessionType sessionType, byte sessionID, int hashId) {
- SdlPacket header = SdlPacketFactory.createEndSession(sessionType, sessionID, hashID, getMajorVersionByte(), BitConverter.intToByteArray(hashId));
- if(sessionType.equals(SessionType.RPC)){ // check for RPC session
- header.putTag(ControlFrameTags.RPC.EndService.HASH_ID, hashID);
- }
+ SdlPacket header;
+ if (sessionType.equals(SessionType.RPC)) { // check for RPC session
+ if(_version < 5){
+ header = SdlPacketFactory.createEndSession(sessionType, sessionID, hashID, getMajorVersionByte(), BitConverter.intToByteArray(hashID));
+ }else{
+ header = SdlPacketFactory.createEndSession(sessionType, sessionID, hashID, getMajorVersionByte(), new byte[0]);
+ header.putTag(ControlFrameTags.RPC.EndService.HASH_ID, hashID);
+ }
+ }else{ //Any other service type we don't include the hash id
+ header = SdlPacketFactory.createEndSession(sessionType, sessionID, hashID, getMajorVersionByte(), new byte[0]);
+ }
handlePacketToSend(header);
} // end-method
@@ -497,6 +504,7 @@ public class WiProProtocol extends AbstractProtocol {
}
handleProtocolSessionStarted(serviceType,(byte) packet.getSessionId(), getMajorVersionByte(), "", hashID, packet.isEncrypted());
} else if (frameInfo == FrameDataControlFrameType.StartSessionNACK.getValue()) {
+ List<String> rejectedParams = null;
if(packet.version >= 5){
String rejectedTag = null;
if(serviceType.equals(SessionType.RPC)){
@@ -506,11 +514,10 @@ public class WiProProtocol extends AbstractProtocol {
}else if(serviceType.equals(SessionType.NAV)){
rejectedTag = ControlFrameTags.Video.StartServiceNAK.REJECTED_PARAMS;
}
- List<String> rejectedParams = (List<String>) packet.getTag(rejectedTag);
- // TODO: Pass these back
+ rejectedParams = (List<String>) packet.getTag(rejectedTag);
}
if (serviceType.eq(SessionType.NAV) || serviceType.eq(SessionType.PCM)) {
- handleProtocolSessionNACKed(serviceType, (byte)packet.getSessionId(), getMajorVersionByte(), "");
+ handleProtocolSessionNACKed(serviceType, (byte)packet.getSessionId(), getMajorVersionByte(), "", rejectedParams);
} else {
handleProtocolError("Got StartSessionNACK for protocol sessionID=" + packet.getSessionId(), null);
}
@@ -637,8 +644,12 @@ public class WiProProtocol extends AbstractProtocol {
@Override
public void EndProtocolService(SessionType serviceType, byte sessionID) {
- SdlPacket header = SdlPacketFactory.createEndSession(serviceType, sessionID, hashID, getMajorVersionByte(), new byte[4]);
- handlePacketToSend(header);
+ if(serviceType.equals(SessionType.RPC)){ //RPC session will close all other sessions so we want to make sure we use the correct EndProtocolSession method
+ EndProtocolSession(serviceType,sessionID,hashID);
+ }else {
+ SdlPacket header = SdlPacketFactory.createEndSession(serviceType, sessionID, hashID, getMajorVersionByte(), new byte[0]);
+ handlePacketToSend(header);
+ }
}
} // end-class
diff --git a/sdl_android/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java b/sdl_android/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java
index 06116c5b9..412d3f857 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/protocol/enums/FunctionID.java
@@ -53,6 +53,11 @@ public enum FunctionID{
SYSTEM_REQUEST(38, "SystemRequest"),
SEND_LOCATION(39, "SendLocation"),
DIAL_NUMBER(40, "DialNumber"),
+
+ BUTTON_PRESS(41, "ButtonPress"),
+ GET_INTERIOR_VEHICLE_DATA(43, "GetInteriorVehicleData"),
+ SET_INTERIOR_VEHICLE_DATA(44, "SetInteriorVehicleData"),
+
GET_WAY_POINTS(45, "GetWayPoints"),
SUBSCRIBE_WAY_POINTS(46, "SubscribeWayPoints"),
UNSUBSCRIBE_WAY_POINTS(47, "UnsubscribeWayPoints"),
@@ -75,6 +80,7 @@ public enum FunctionID{
ON_TOUCH_EVENT(32780, "OnTouchEvent"),
ON_SYSTEM_REQUEST(32781, "OnSystemRequest"),
ON_HASH_CHANGE(32782, "OnHashChange"),
+ ON_INTERIOR_VEHICLE_DATA(32783, "OnInteriorVehicleData"),
ON_WAY_POINT_CHANGE(32784, "OnWayPointChange"),
// MOCKED FUNCTIONS (NOT SENT FROM HEAD-UNIT)
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
index a8e184517..8614791d0 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java
@@ -12,6 +12,7 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
@@ -45,6 +46,7 @@ import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.exception.SdlExceptionCause;
import com.smartdevicelink.marshal.JsonRPCMarshaller;
import com.smartdevicelink.protocol.ProtocolMessage;
+import com.smartdevicelink.protocol.enums.ControlFrameTags;
import com.smartdevicelink.protocol.enums.FunctionID;
import com.smartdevicelink.protocol.enums.MessageType;
import com.smartdevicelink.protocol.enums.SessionType;
@@ -55,10 +57,12 @@ import com.smartdevicelink.proxy.callbacks.OnError;
import com.smartdevicelink.proxy.callbacks.OnProxyClosed;
import com.smartdevicelink.proxy.callbacks.OnServiceEnded;
import com.smartdevicelink.proxy.callbacks.OnServiceNACKed;
-import com.smartdevicelink.proxy.interfaces.IProxyListenerALM;
+import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
import com.smartdevicelink.proxy.interfaces.IProxyListenerBase;
import com.smartdevicelink.proxy.interfaces.IPutFileResponseListener;
+import com.smartdevicelink.proxy.interfaces.ISdl;
import com.smartdevicelink.proxy.interfaces.ISdlServiceListener;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.*;
import com.smartdevicelink.proxy.rpc.enums.AppHMIType;
@@ -70,7 +74,6 @@ import com.smartdevicelink.proxy.rpc.enums.DriverDistractionState;
import com.smartdevicelink.proxy.rpc.enums.FileType;
import com.smartdevicelink.proxy.rpc.enums.GlobalProperty;
import com.smartdevicelink.proxy.rpc.enums.HMILevel;
-import com.smartdevicelink.proxy.rpc.enums.HmiZoneCapabilities;
import com.smartdevicelink.proxy.rpc.enums.ImageType;
import com.smartdevicelink.proxy.rpc.enums.InteractionMode;
import com.smartdevicelink.proxy.rpc.enums.Language;
@@ -81,16 +84,17 @@ import com.smartdevicelink.proxy.rpc.enums.SamplingRate;
import com.smartdevicelink.proxy.rpc.enums.SdlConnectionState;
import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason;
import com.smartdevicelink.proxy.rpc.enums.SdlInterfaceAvailability;
-import com.smartdevicelink.proxy.rpc.enums.SpeechCapabilities;
import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
-import com.smartdevicelink.proxy.rpc.enums.SystemContext;
import com.smartdevicelink.proxy.rpc.enums.TextAlignment;
import com.smartdevicelink.proxy.rpc.enums.UpdateMode;
-import com.smartdevicelink.proxy.rpc.enums.VrCapabilities;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingCodec;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingProtocol;
import com.smartdevicelink.proxy.rpc.listeners.OnPutFileUpdateListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
import com.smartdevicelink.security.SdlSecurityBase;
+import com.smartdevicelink.streaming.AudioStreamingCodec;
+import com.smartdevicelink.streaming.AudioStreamingParams;
import com.smartdevicelink.streaming.StreamRPCPacketizer;
import com.smartdevicelink.streaming.VideoStreamingParameters;
import com.smartdevicelink.trace.SdlTrace;
@@ -101,6 +105,7 @@ import com.smartdevicelink.transport.SiphonServer;
import com.smartdevicelink.transport.enums.TransportType;
import com.smartdevicelink.util.DebugTool;
+@SuppressWarnings({"WeakerAccess", "Convert2Diamond"})
public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> {
// Used for calls to Android Log class.
public static final String TAG = "SdlProxy";
@@ -108,6 +113,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
private static final int PROX_PROT_VER_ONE = 1;
private static final int RESPONSE_WAIT_TIME = 2000;
+ private static final VideoStreamingFormat VIDEO_STREAMING_FORMAT_H264_RAW = new VideoStreamingFormat(VideoStreamingCodec.H264,VideoStreamingProtocol.RAW);
+ private static final VideoStreamingFormat VIDEO_STREAMING_FORMAT_H264_RTP = new VideoStreamingFormat(VideoStreamingCodec.H264,VideoStreamingProtocol.RTP);
+
private SdlSession sdlSession = null;
private proxyListenerType _proxyListener = null;
@@ -127,14 +135,17 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
ON_UPDATE_LISTENER_LOCK = new Object(),
ON_NOTIFICATION_LISTENER_LOCK = new Object();
- private Object APP_INTERFACE_REGISTERED_LOCK = new Object();
+ private final Object APP_INTERFACE_REGISTERED_LOCK = new Object();
private int iFileCount = 0;
private boolean navServiceStartResponseReceived = false;
private boolean navServiceStartResponse = false;
+ private List<String> navServiceStartRejectedParams = null;
private boolean pcmServiceStartResponseReceived = false;
private boolean pcmServiceStartResponse = false;
+ @SuppressWarnings("FieldCanBeLocal")
+ private List<String> pcmServiceStartRejectedParams = null;
private boolean navServiceEndResponseReceived = false;
private boolean navServiceEndResponse = false;
private boolean pcmServiceEndResponseReceived = false;
@@ -160,7 +171,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
protected Boolean _advancedLifecycleManagementEnabled = false;
// Parameters passed to the constructor from the app to register an app interface
private String _applicationName = null;
- private long instanceDateTime = System.currentTimeMillis();
+ private final long instanceDateTime = System.currentTimeMillis();
private String sConnectionDetails = "N/A";
private Vector<TTSChunk> _ttsName = null;
private String _ngnMediaScreenAppName = null;
@@ -169,8 +180,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
private Language _hmiDisplayLanguageDesired = null;
private Vector<AppHMIType> _appType = null;
private String _appID = null;
+ @SuppressWarnings({"FieldCanBeLocal", "unused"}) //Need to understand what this is used for
private String _autoActivateIdDesired = null;
- private String _lastHashID = null;
+ private String _lastHashID = null;
private SdlMsgVersion _sdlMsgVersionRequest = null;
private Vector<String> _vrSynonyms = null;
private boolean _bAppResumeEnabled = false;
@@ -186,7 +198,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
// Proxy State Variables
protected Boolean _appInterfaceRegisterd = false;
protected Boolean _preRegisterd = false;
- @SuppressWarnings("unused")
+ @SuppressWarnings({"unused", "FieldCanBeLocal"})
private Boolean _haveReceivedFirstNonNoneHMILevel = false;
protected Boolean _haveReceivedFirstFocusLevel = false;
protected Boolean _haveReceivedFirstFocusLevelFull = false;
@@ -194,10 +206,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
protected SdlConnectionState _sdlConnectionState = null;
protected SdlInterfaceAvailability _sdlIntefaceAvailablity = null;
protected HMILevel _hmiLevel = null;
- private HMILevel _priorHmiLevel = null;
protected AudioStreamingState _audioStreamingState = null;
- private AudioStreamingState _priorAudioStreamingState = null;
- protected SystemContext _systemContext = null;
// Variables set by RegisterAppInterfaceResponse
protected SdlMsgVersion _sdlMsgVersion = null;
protected String _autoActivateIdReturned = null;
@@ -213,15 +222,102 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
protected List<Class<? extends SdlSecurityBase>> _secList = null;
protected SystemCapabilityManager _systemCapabilityManager;
- private CopyOnWriteArrayList<IPutFileResponseListener> _putFileListenerList = new CopyOnWriteArrayList<IPutFileResponseListener>();
+ private final CopyOnWriteArrayList<IPutFileResponseListener> _putFileListenerList = new CopyOnWriteArrayList<IPutFileResponseListener>();
protected byte _wiproVersion = 1;
protected SparseArray<OnRPCResponseListener> rpcResponseListeners = null;
- protected SparseArray<OnRPCNotificationListener> rpcNotificationListeners = null;
-
+ protected SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>> rpcNotificationListeners = null;
+
+
// Interface broker
private SdlInterfaceBroker _interfaceBroker = null;
+ //We create an easily passable anonymous class of the interface so that we don't expose the internal interface to developers
+ private ISdl _internalInterface = new ISdl() {
+ @Override
+ public void start() {
+ try{
+ initializeProxy();
+ }catch (SdlException e){
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void stop() {
+ try{
+ dispose();
+ }catch (SdlException e){
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ return getIsConnected();
+ }
+
+ @Override
+ public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
+ if(sdlSession!=null){
+ sdlSession.addServiceListener(serviceType,sdlServiceListener);
+ }
+ }
+
+ @Override
+ public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) {
+ if(sdlSession!=null){
+ sdlSession.removeServiceListener(serviceType,sdlServiceListener);
+ }
+ }
+
+ @Override
+ public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) {
+ if(isConnected()){
+ sdlSession.startService(SessionType.NAV,sdlSession.getSessionId(),encrypted);
+ }
+ }
+
+ @Override
+ public void stopVideoService() {
+ if(isConnected()){
+ sdlSession.endService(SessionType.NAV,sdlSession.getSessionId());
+ }
+ }
+
+ @Override
+ public void startAudioService(boolean encrypted) {
+ if(isConnected()){
+ sdlSession.startService(SessionType.PCM,sdlSession.getSessionId(),encrypted);
+ }
+ }
+
+ @Override
+ public void stopAudioService() {
+ if(isConnected()){
+ sdlSession.endService(SessionType.PCM,sdlSession.getSessionId());
+ }
+ }
+
+ @Override
+ public void sendRPCRequest(RPCRequest message){
+ try {
+ SdlProxyBase.this.sendRPCRequest(message);
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {
+ SdlProxyBase.this.addOnRPCNotificationListener(notificationId,listener);
+ }
+
+ @Override
+ public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) {
+ return SdlProxyBase.this.removeOnRPCNotificationListener(notificationId,listener);
+ }
+ };
private void notifyPutFileStreamError(Exception e, String info)
{
@@ -256,12 +352,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
// disconnect has completed
notifyPutFileStreamError(null, info);
- if (_advancedLifecycleManagementEnabled) {
- // If ALM, nothing is required to be done here
- } else {
+ if (!_advancedLifecycleManagementEnabled) {
// If original model, notify app the proxy is closed so it will delete and reinstanciate
notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT);
- }
+ }// else If ALM, nothing is required to be done here
+
}
@Override
@@ -322,7 +417,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
sdlSession.setIncomingHeartbeatMonitor(incomingHeartbeatMonitor);
}
- startRPCProtocolSession(sessionID, correlationID);
+ startRPCProtocolSession();
}
else
{
@@ -337,15 +432,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
else if (_wiproVersion > 1) {
//If version is 2 or above then don't need to specify a Session Type
- startRPCProtocolSession(sessionID, correlationID);
- } else {
- // Handle other protocol session types here
- }
+ startRPCProtocolSession();
+ } //else{} Handle other protocol session types here
+
}
@Override
public void onProtocolSessionStartedNACKed(SessionType sessionType,
- byte sessionID, byte version, String correlationID) {
+ byte sessionID, byte version, String correlationID, List<String> rejectedParams) {
OnServiceNACKed message = new OnServiceNACKed(sessionType);
queueInternalMessage(message);
@@ -357,7 +451,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName());
sendBroadcastIntent(sendIntent);
- NavServiceStartedNACK();
+ NavServiceStartedNACK(rejectedParams);
}
else if (sessionType.eq(SessionType.PCM)) {
Intent sendIntent = createBroadcastIntent();
@@ -366,7 +460,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
updateBroadcastIntent(sendIntent, "COMMENT2", " NACK ServiceType: " + sessionType.getName());
sendBroadcastIntent(sendIntent);
- AudioServiceStartedNACK();
+ AudioServiceStartedNACK(rejectedParams);
}
}
@@ -476,7 +570,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param autoActivateID Auto activation identifier.
* @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not.
* @param transportConfig Configuration of transport to be used by underlying connection.
- * @throws SdlException
+ * @throws SdlException if there is an unrecoverable error class might throw an exception.
*/
protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
@@ -489,12 +583,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
sdlMsgVersion, languageDesired, hmiDisplayLanguageDesired, appType, appID, autoActivateID, callbackToUIThread, null, null, null, transportConfig);
}
- private void performBaseCommon(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
- boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
- String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
- Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
- String autoActivateID, boolean callbackToUIThread, Boolean preRegister, String sHashID, Boolean bAppResumeEnab,
- BaseTransportConfig transportConfig) throws SdlException
+ @SuppressWarnings("ConstantConditions")
+ private void performBaseCommon(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
+ boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
+ String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp, SdlMsgVersion sdlMsgVersion,
+ Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType, String appID,
+ String autoActivateID, boolean callbackToUIThread, Boolean preRegister, String sHashID, Boolean bAppResumeEnab,
+ BaseTransportConfig transportConfig) throws SdlException
{
setWiProVersion((byte)PROX_PROT_VER_ONE);
@@ -578,7 +673,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
@Override
public void dispatch(InternalProxyMessage message) {
- dispatchInternalMessage((InternalProxyMessage)message);
+ dispatchInternalMessage(message);
}
@Override
@@ -604,7 +699,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_incomingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("INCOMING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() {
@Override
public void dispatch(ProtocolMessage message) {
- dispatchIncomingMessage((ProtocolMessage)message);
+ dispatchIncomingMessage(message);
}
@Override
@@ -630,7 +725,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_outgoingProxyMessageDispatcher = new ProxyMessageDispatcher<ProtocolMessage>("OUTGOING_MESSAGE_DISPATCHER",new IDispatchingStrategy<ProtocolMessage>() {
@Override
public void dispatch(ProtocolMessage message) {
- dispatchOutgoingMessage((ProtocolMessage)message);
+ dispatchOutgoingMessage(message);
}
@Override
@@ -646,19 +741,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
rpcResponseListeners = new SparseArray<OnRPCResponseListener>();
- rpcNotificationListeners = new SparseArray<OnRPCNotificationListener>();
-
- //Initialize _systemCapabilityManager here.
- _systemCapabilityManager = new SystemCapabilityManager(new SystemCapabilityManager.ISystemCapabilityManager() {
- @Override
- public void onSendPacketRequest(RPCRequest message) {
- try {
- sendRPCRequest(message);
- } catch (SdlException e) {
- e.printStackTrace();
- }
- }
- });
+ rpcNotificationListeners = new SparseArray<CopyOnWriteArrayList<OnRPCNotificationListener>>();
// Initialize the proxy
try {
@@ -719,7 +802,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param callbackToUIThread Flag that indicates that this proxy should send callback to UI thread or not.
* @param preRegister Flag that indicates that this proxy should be pre-registerd or not.
* @param transportConfig Configuration of transport to be used by underlying connection.
- * @throws SdlException
+ * @throws SdlException if there is an unrecoverable error class might throw an exception.
*/
protected SdlProxyBase(proxyListenerType listener, SdlProxyConfigurationResources sdlProxyConfigurationResources,
boolean enableAdvancedLifecycleManagement, String appName, Vector<TTSChunk> ttsName,
@@ -799,7 +882,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
private void sendBroadcastIntent(Intent sendIntent)
{
- Service myService = null;
+ Service myService;
if (_proxyListener != null && _proxyListener instanceof Service)
{
myService = (Service) _proxyListener;
@@ -837,8 +920,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
String sCharSet = "utf-8";
int iContentLength = iContentLen;
- URL url = null;
- HttpURLConnection urlConnection = null;
+ URL url;
+ HttpURLConnection urlConnection;
Intent sendIntent = createBroadcastIntent();
updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "getURLConnection");
@@ -912,7 +995,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
Headers myHeader = msg.getHeader();
- updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "sendOnSystemRequestToUrl");
+ updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "sendOnSystemRequestToUrl");
updateBroadcastIntent(sendIntent, "COMMENT5", "\r\nCloud URL: " + sURLString);
try
@@ -975,9 +1058,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
wr.close();
- long BeforeTime = System.currentTimeMillis();
- @SuppressWarnings("unused")
- String sResponseMsg = urlConnection.getResponseMessage();
+ long BeforeTime = System.currentTimeMillis();
long AfterTime = System.currentTimeMillis();
final long roundtriptime = AfterTime - BeforeTime;
@@ -1014,7 +1095,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + response.toString());
sendRPCRequestPrivate(putFile);
- Log.i("sendOnSystemRequestToUrl", "sent to sdl");
+ Log.i("sendSystemRequestToUrl", "sent to sdl");
updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.PUT_FILE.toString());
updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
@@ -1034,20 +1115,20 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
if (jsonArray.get(i) instanceof String)
{
cloudDataReceived.add(jsonArray.getString(i));
- //Log.i("sendOnSystemRequestToUrl", "jsonArray.getString(i): " + jsonArray.getString(i));
+ //Log.i("sendSystemRequestToUrl", "jsonArray.getString(i): " + jsonArray.getString(i));
}
}
}
else if (jsonResponse.get(dataKey) instanceof String)
{
cloudDataReceived.add(jsonResponse.getString(dataKey));
- //Log.i("sendOnSystemRequestToUrl", "jsonResponse.getString(data): " + jsonResponse.getString("data"));
+ //Log.i("sendSystemRequestToUrl", "jsonResponse.getString(data): " + jsonResponse.getString("data"));
}
}
else
{
- DebugTool.logError("sendOnSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
- //Log.i("sendOnSystemRequestToUrl", "sendOnSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
+ DebugTool.logError("sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
+ //Log.i("sendSystemRequestToUrl", "sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
return;
}
@@ -1069,10 +1150,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
mySystemRequest = RPCRequestFactory.buildSystemRequest(response.toString(), getPoliciesReservedCorrelationID());
}
- if (getIsConnected())
+ if (getIsConnected())
{
sendRPCRequestPrivate(mySystemRequest);
- Log.i("sendOnSystemRequestToUrl", "sent to sdl");
+ Log.i("sendSystemRequestToUrl", "sent to sdl");
updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
@@ -1082,45 +1163,45 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
catch (SdlException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: Could not get data from JSONObject received.", e);
+ DebugTool.logError("sendSystemRequestToUrl: Could not get data from JSONObject received.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " SdlException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: Could not get data from JSONObject received."+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: Could not get data from JSONObject received."+ e);
}
catch (JSONException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: JSONException: ", e);
+ DebugTool.logError("sendSystemRequestToUrl: JSONException: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " JSONException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: JSONException: "+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: JSONException: "+ e);
}
catch (UnsupportedEncodingException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: Could not encode string.", e);
+ DebugTool.logError("sendSystemRequestToUrl: Could not encode string.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " UnsupportedEncodingException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: Could not encode string."+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: Could not encode string."+ e);
}
catch (ProtocolException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: Could not set request method to post.", e);
+ DebugTool.logError("sendSystemRequestToUrl: Could not set request method to post.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " ProtocolException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: Could not set request method to post."+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: Could not set request method to post."+ e);
}
catch (MalformedURLException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e);
+ DebugTool.logError("sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " MalformedURLException encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: URL Exception when sending SystemRequest to an external server."+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server."+ e);
}
catch (IOException e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: IOException: ", e);
+ DebugTool.logError("sendSystemRequestToUrl: IOException: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " IOException while sending to cloud: IOException: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: IOException: "+ e);
+ //Log.i("pt", "sendSystemRequestToUrl: IOException: "+ e);
}
catch (Exception e)
{
- DebugTool.logError("sendOnSystemRequestToUrl: Unexpected Exception: ", e);
+ DebugTool.logError("sendSystemRequestToUrl: Unexpected Exception: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " Exception encountered sendOnSystemRequestToUrl: "+ e);
- //Log.i("pt", "sendOnSystemRequestToUrl: Unexpected Exception: " + e);
+ //Log.i("pt", "sendSystemRequestToUrl: Unexpected Exception: " + e);
}
finally
{
@@ -1145,23 +1226,19 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
// Test correlationID
private boolean isCorrelationIDProtected(Integer correlationID) {
- if (correlationID != null &&
- (HEARTBEAT_CORRELATION_ID == correlationID
+ return correlationID != null &&
+ (HEARTBEAT_CORRELATION_ID == correlationID
|| REGISTER_APP_INTERFACE_CORRELATION_ID == correlationID
|| UNREGISTER_APP_INTERFACE_CORRELATION_ID == correlationID
- || POLICIES_CORRELATION_ID == correlationID)) {
- return true;
- }
-
- return false;
+ || POLICIES_CORRELATION_ID == correlationID);
+
}
// Protected isConnected method to allow legacy proxy to poll isConnected state
public Boolean getIsConnected() {
- if (sdlSession == null) return false;
-
- return sdlSession.getIsConnected();
+ return sdlSession != null && sdlSession.getIsConnected();
}
+
/**
* Returns whether the application is registered in SDL. Note: for testing
@@ -1180,15 +1257,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_haveReceivedFirstNonNoneHMILevel = false;
_haveReceivedFirstFocusLevel = false;
_haveReceivedFirstFocusLevelFull = false;
- if (_preRegisterd)
- _appInterfaceRegisterd = true;
- else
- _appInterfaceRegisterd = false;
+ _appInterfaceRegisterd = _preRegisterd;
_putFileListenerList.clear();
_sdlIntefaceAvailablity = SdlInterfaceAvailability.SDL_INTERFACE_UNAVAILABLE;
-
+
+ //Initialize _systemCapabilityManager here.
+ _systemCapabilityManager = new SystemCapabilityManager(_internalInterface);
// Setup SdlConnection
synchronized(CONNECTION_REFERENCE_LOCK) {
this.sdlSession = SdlSession.createSession(_wiproVersion,_interfaceBroker, _transportConfig);
@@ -1201,8 +1277,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
/**
* This method will fake the multiplex connection event
- * @param action
*/
+ @SuppressWarnings("unused")
public void forceOnConnected(){
synchronized(CONNECTION_REFERENCE_LOCK) {
if (sdlSession != null) {
@@ -1237,6 +1313,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Public method to enable the siphon transport
*/
+ @SuppressWarnings("unused")
public void enableSiphonDebug() {
short enabledPortNumber = SiphonServer.enableSiphonServer();
@@ -1252,6 +1329,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Public method to disable the Siphon Trace Server
*/
+ @SuppressWarnings("unused")
public void disableSiphonDebug() {
short disabledPortNumber = SiphonServer.disableSiphonServer();
@@ -1283,16 +1361,19 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Public method to determine Debug Tool enabled
*/
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isDebugEnabled() {
return DebugTool.isDebugEnabled();
}
+ @SuppressWarnings("unused")
@Deprecated
public void close() throws SdlException {
dispose();
}
+ @SuppressWarnings("UnusedParameters")
private void cleanProxy(SdlDisconnectedReason disconnectedReason) throws SdlException {
try {
@@ -1306,7 +1387,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
Boolean waitForInterfaceUnregistered = false;
// Unregister app interface
synchronized(CONNECTION_REFERENCE_LOCK) {
- if (sdlSession != null && sdlSession.getIsConnected() && getAppInterfaceRegistered()) {
+ if (getIsConnected() && getAppInterfaceRegistered()) {
waitForInterfaceUnregistered = true;
unregisterAppInterfacePrivate(UNREGISTER_APP_INTERFACE_CORRELATION_ID);
}
@@ -1328,15 +1409,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
rpcResponseListeners.clear();
}
if(rpcNotificationListeners != null){
- rpcNotificationListeners.clear(); //TODO make sure we want to clear this
+ rpcNotificationListeners.clear();
}
// Clean up SDL Connection
synchronized(CONNECTION_REFERENCE_LOCK) {
if (sdlSession != null) sdlSession.close();
}
- } catch (SdlException e) {
- throw e;
} finally {
SdlTrace.logProxyEvent("SdlProxy cleaned.", SDL_LIB_TRACE_KEY);
}
@@ -1387,15 +1466,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
rpcResponseListeners = null;
- } catch (SdlException e) {
- throw e;
} finally {
SdlTrace.logProxyEvent("SdlProxy disposed.", SDL_LIB_TRACE_KEY);
}
} // end-method
- private static Object CYCLE_LOCK = new Object();
+ private final static Object CYCLE_LOCK = new Object();
private boolean _cycling = false;
@@ -1479,17 +1556,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
if (message.getBulkData() != null) hash.put(RPCStruct.KEY_BULK_DATA, message.getBulkData());
if (message.getPayloadProtected()) hash.put(RPCStruct.KEY_PROTECTED, true);
} else {
- final Hashtable<String, Object> mhash = JsonRPCMarshaller.unmarshall(message.getData());
- hash = mhash;
+ hash = JsonRPCMarshaller.unmarshall(message.getData());
}
handleRPCMessage(hash);
} catch (final Exception excp) {
DebugTool.logError("Failure handling protocol message: " + excp.toString(), excp);
passErrorToProxyListener("Error handing incoming protocol message.", excp);
} // end-catch
- } else {
- // Handle other protocol message types here
- }
+ } //else { Handle other protocol message types here}
} catch (final Exception e) {
// Pass error to application through listener
DebugTool.logError("Error handing proxy event.", e);
@@ -1507,7 +1581,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
public String serializeJSON(RPCMessage msg)
{
- String sReturn = null;
+ String sReturn;
try
{
sReturn = msg.serializeJSON(getWiProVersion()).toString(2);
@@ -1540,77 +1614,88 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
void dispatchInternalMessage(final InternalProxyMessage message) {
try{
- if (message.getFunctionName().equals(InternalProxyMessage.OnProxyError)) {
- final OnError msg = (OnError)message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onError(msg.getInfo(), msg.getException());
- }
- });
- } else {
- _proxyListener.onError(msg.getInfo(), msg.getException());
- }
- } else if (message.getFunctionName().equals(InternalProxyMessage.OnServiceEnded)) {
- final OnServiceEnded msg = (OnServiceEnded)message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onServiceEnded(msg);
- }
- });
- } else {
- _proxyListener.onServiceEnded(msg);
+ switch (message.getFunctionName()) {
+ case InternalProxyMessage.OnProxyError: {
+ final OnError msg = (OnError) message;
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onError(msg.getInfo(), msg.getException());
+ }
+ });
+ } else {
+ _proxyListener.onError(msg.getInfo(), msg.getException());
+ }
+ break;
}
- } else if (message.getFunctionName().equals(InternalProxyMessage.OnServiceNACKed)) {
- final OnServiceNACKed msg = (OnServiceNACKed)message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onServiceNACKed(msg);
- }
- });
- } else {
- _proxyListener.onServiceNACKed(msg);
+ case InternalProxyMessage.OnServiceEnded: {
+ final OnServiceEnded msg = (OnServiceEnded) message;
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onServiceEnded(msg);
+ }
+ });
+ } else {
+ _proxyListener.onServiceEnded(msg);
+ }
+ break;
}
+ case InternalProxyMessage.OnServiceNACKed: {
+ final OnServiceNACKed msg = (OnServiceNACKed) message;
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onServiceNACKed(msg);
+ }
+ });
+ } else {
+ _proxyListener.onServiceNACKed(msg);
+ }
- /**************Start Legacy Specific Call-backs************/
- } else if (message.getFunctionName().equals(InternalProxyMessage.OnProxyOpened)) {
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- ((IProxyListener)_proxyListener).onProxyOpened();
- }
- });
- } else {
- ((IProxyListener)_proxyListener).onProxyOpened();
+ /* *************Start Legacy Specific Call-backs************/
+ break;
}
- } else if (message.getFunctionName().equals(InternalProxyMessage.OnProxyClosed)) {
- final OnProxyClosed msg = (OnProxyClosed)message;
- if (_callbackToUIThread) {
- // Run in UI thread
- _mainUIHandler.post(new Runnable() {
- @Override
- public void run() {
- _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
- }
- });
- } else {
- _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
+ case InternalProxyMessage.OnProxyOpened:
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ((IProxyListener) _proxyListener).onProxyOpened();
+ }
+ });
+ } else {
+ ((IProxyListener) _proxyListener).onProxyOpened();
+ }
+ break;
+ case InternalProxyMessage.OnProxyClosed: {
+ final OnProxyClosed msg = (OnProxyClosed) message;
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
+ }
+ });
+ } else {
+ _proxyListener.onProxyClosed(msg.getInfo(), msg.getException(), msg.getReason());
+ }
+ /* ***************End Legacy Specific Call-backs************/
+ break;
}
- /****************End Legacy Specific Call-backs************/
- } else {
- // Diagnostics
- SdlTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.", SDL_LIB_TRACE_KEY);
- DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.");
+ default:
+ // Diagnostics
+ SdlTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.", SDL_LIB_TRACE_KEY);
+ DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.");
+ break;
}
SdlTrace.logProxyEvent("Proxy fired callback: " + message.getFunctionName(), SDL_LIB_TRACE_KEY);
@@ -1694,10 +1779,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Only call this method for a PutFile response. It will cause a class cast exception if not.
- * @param correlationId
- * @param bytesWritten
- * @param totalSize
+ * @param correlationId correlation id of the packet being updated
+ * @param bytesWritten how many bytes were written
+ * @param totalSize the total size in bytes
*/
+ @SuppressWarnings("unused")
public void onPacketProgress(int correlationId, long bytesWritten, long totalSize){
synchronized(ON_UPDATE_LISTENER_LOCK){
if(rpcResponseListeners !=null
@@ -1711,9 +1797,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Will provide callback to the listener either onFinish or onError depending on the RPCResponses result code,
* <p>Will automatically remove the listener for the list of listeners on completion.
- * @param msg
+ * @param msg The RPCResponse message that was received
* @return if a listener was called or not
*/
+ @SuppressWarnings("UnusedReturnValue")
private boolean onRPCResponseReceived(RPCResponse msg){
synchronized(ON_UPDATE_LISTENER_LOCK){
int correlationId = msg.getCorrelationID();
@@ -1733,9 +1820,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
/**
- *
- * @param listener
- * @param correlationId
+ * Add a listener that will receive the response to the specific RPCRequest sent with the corresponding correlation id
+ * @param listener that will get called back when a response is received
+ * @param correlationId of the RPCRequest that was sent
* @param totalSize only include if this is an OnPutFileUpdateListener. Otherwise it will be ignored.
*/
public void addOnRPCResponseListener(OnRPCResponseListener listener,int correlationId, int totalSize){
@@ -1751,17 +1838,21 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
}
+ @SuppressWarnings("unused")
public SparseArray<OnRPCResponseListener> getResponseListeners(){
synchronized(ON_UPDATE_LISTENER_LOCK){
return this.rpcResponseListeners;
}
}
+ @SuppressWarnings("UnusedReturnValue")
public boolean onRPCNotificationReceived(RPCNotification notification){
synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- OnRPCNotificationListener listener = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName()));
- if(listener!=null){
- listener.onNotified(notification);
+ CopyOnWriteArrayList<OnRPCNotificationListener> listeners = rpcNotificationListeners.get(FunctionID.getFunctionId(notification.getFunctionName()));
+ if(listeners!=null && listeners.size()>0) {
+ for (OnRPCNotificationListener listener : listeners) {
+ listener.onNotified(notification);
+ }
return true;
}
return false;
@@ -1771,20 +1862,45 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* This will ad a listener for the specific type of notification. As of now it will only allow
* a single listener per notification function id
- * @param notification The notification type that this listener is designated for
+ * @param notificationId The notification type that this listener is designated for
* @param listener The listener that will be called when a notification of the provided type is received
*/
- public void addOnRPCNotificationListener(FunctionID notificationId,OnRPCNotificationListener listener){
+ @SuppressWarnings("unused")
+ public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- rpcNotificationListeners.put(notificationId.getId(), listener);
+ if(notificationId != null && listener != null){
+ if(rpcNotificationListeners.indexOfKey(notificationId.getId()) < 0 ){
+ rpcNotificationListeners.put(notificationId.getId(),new CopyOnWriteArrayList<OnRPCNotificationListener>());
+ }
+ rpcNotificationListeners.get(notificationId.getId()).add(listener);
+ }
}
}
-
+
+ /**
+ * This method is no longer valid and will not remove the listener for the supplied notificaiton id
+ * @param notificationId n/a
+ * @see #removeOnRPCNotificationListener(FunctionID, OnRPCNotificationListener)
+ */
+ @SuppressWarnings("unused")
+ @Deprecated
public void removeOnRPCNotificationListener(FunctionID notificationId){
synchronized(ON_NOTIFICATION_LISTENER_LOCK){
- rpcNotificationListeners.delete(notificationId.getId());
+ //rpcNotificationListeners.delete(notificationId.getId());
}
}
+
+ public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){
+ synchronized(ON_NOTIFICATION_LISTENER_LOCK){
+ if(rpcNotificationListeners!= null
+ && notificationId != null
+ && listener != null
+ && rpcNotificationListeners.indexOfKey(notificationId.getId()) >= 0){
+ return rpcNotificationListeners.get(notificationId.getId()).remove(listener);
+ }
+ }
+ return false;
+ }
private void processRaiResponse(RegisterAppInterfaceResponse rai)
{
@@ -1798,7 +1914,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
if (_secList == null) return;
- SdlSecurityBase sec = null;
+ SdlSecurityBase sec;
Service svc = getService();
SdlSecurityBase.setAppService(svc);
@@ -1818,12 +1934,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
if (sec.getMakeList().contains(make))
{
setSdlSecurity(sec);
- if (sec != null)
- {
sec.setAppId(_appID);
if (sdlSession != null)
sec.handleSdlSession(sdlSession);
- }
return;
}
}
@@ -1920,8 +2033,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
public void run() {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onRegisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -1929,8 +2040,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
} else {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onRegisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -2064,8 +2173,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
public void run() {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onRegisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -2073,8 +2180,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
} else {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onRegisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onRegisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -2122,12 +2227,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onShowResponse((ShowResponse)msg);
+ _proxyListener.onShowResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onShowResponse((ShowResponse)msg);
+ _proxyListener.onShowResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.ADD_COMMAND.toString())) {
@@ -2139,12 +2244,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onAddCommandResponse((AddCommandResponse)msg);
+ _proxyListener.onAddCommandResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onAddCommandResponse((AddCommandResponse)msg);
+ _proxyListener.onAddCommandResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.DELETE_COMMAND.toString())) {
@@ -2156,12 +2261,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onDeleteCommandResponse((DeleteCommandResponse)msg);
+ _proxyListener.onDeleteCommandResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onDeleteCommandResponse((DeleteCommandResponse)msg);
+ _proxyListener.onDeleteCommandResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.ADD_SUB_MENU.toString())) {
@@ -2173,12 +2278,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onAddSubMenuResponse((AddSubMenuResponse)msg);
+ _proxyListener.onAddSubMenuResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onAddSubMenuResponse((AddSubMenuResponse)msg);
+ _proxyListener.onAddSubMenuResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.DELETE_SUB_MENU.toString())) {
@@ -2190,12 +2295,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onDeleteSubMenuResponse((DeleteSubMenuResponse)msg);
+ _proxyListener.onDeleteSubMenuResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onDeleteSubMenuResponse((DeleteSubMenuResponse)msg);
+ _proxyListener.onDeleteSubMenuResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SUBSCRIBE_BUTTON.toString())) {
@@ -2207,12 +2312,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSubscribeButtonResponse((SubscribeButtonResponse)msg);
+ _proxyListener.onSubscribeButtonResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSubscribeButtonResponse((SubscribeButtonResponse)msg);
+ _proxyListener.onSubscribeButtonResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.UNSUBSCRIBE_BUTTON.toString())) {
@@ -2224,12 +2329,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onUnsubscribeButtonResponse((UnsubscribeButtonResponse)msg);
+ _proxyListener.onUnsubscribeButtonResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onUnsubscribeButtonResponse((UnsubscribeButtonResponse)msg);
+ _proxyListener.onUnsubscribeButtonResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SET_MEDIA_CLOCK_TIMER.toString())) {
@@ -2241,12 +2346,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSetMediaClockTimerResponse((SetMediaClockTimerResponse)msg);
+ _proxyListener.onSetMediaClockTimerResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSetMediaClockTimerResponse((SetMediaClockTimerResponse)msg);
+ _proxyListener.onSetMediaClockTimerResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) {
@@ -2284,12 +2389,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onCreateInteractionChoiceSetResponse((CreateInteractionChoiceSetResponse)msg);
+ _proxyListener.onCreateInteractionChoiceSetResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onCreateInteractionChoiceSetResponse((CreateInteractionChoiceSetResponse)msg);
+ _proxyListener.onCreateInteractionChoiceSetResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.DELETE_INTERACTION_CHOICE_SET.toString())) {
@@ -2301,12 +2406,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onDeleteInteractionChoiceSetResponse((DeleteInteractionChoiceSetResponse)msg);
+ _proxyListener.onDeleteInteractionChoiceSetResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onDeleteInteractionChoiceSetResponse((DeleteInteractionChoiceSetResponse)msg);
+ _proxyListener.onDeleteInteractionChoiceSetResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.PERFORM_INTERACTION.toString())) {
@@ -2318,12 +2423,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onPerformInteractionResponse((PerformInteractionResponse)msg);
+ _proxyListener.onPerformInteractionResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onPerformInteractionResponse((PerformInteractionResponse)msg);
+ _proxyListener.onPerformInteractionResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SET_GLOBAL_PROPERTIES.toString())) {
@@ -2335,12 +2440,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSetGlobalPropertiesResponse((SetGlobalPropertiesResponse)msg);
+ _proxyListener.onSetGlobalPropertiesResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSetGlobalPropertiesResponse((SetGlobalPropertiesResponse)msg);
+ _proxyListener.onSetGlobalPropertiesResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.RESET_GLOBAL_PROPERTIES.toString())) {
@@ -2352,12 +2457,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onResetGlobalPropertiesResponse((ResetGlobalPropertiesResponse)msg);
+ _proxyListener.onResetGlobalPropertiesResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onResetGlobalPropertiesResponse((ResetGlobalPropertiesResponse)msg);
+ _proxyListener.onResetGlobalPropertiesResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.UNREGISTER_APP_INTERFACE.toString())) {
@@ -2387,8 +2492,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
public void run() {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onUnregisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -2396,8 +2499,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
} else {
if (_proxyListener instanceof IProxyListener) {
((IProxyListener)_proxyListener).onUnregisterAppInterfaceResponse(msg);
- } else if (_proxyListener instanceof IProxyListenerALM) {
- //((IProxyListenerALM)_proxyListener).onUnregisterAppInterfaceResponse(msg);
}
onRPCResponseReceived(msg);
}
@@ -2411,12 +2512,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onGenericResponse((GenericResponse)msg);
+ _proxyListener.onGenericResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onGenericResponse((GenericResponse)msg);
+ _proxyListener.onGenericResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SLIDER.toString())) {
@@ -2427,12 +2528,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSliderResponse((SliderResponse)msg);
+ _proxyListener.onSliderResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSliderResponse((SliderResponse)msg);
+ _proxyListener.onSliderResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.PUT_FILE.toString())) {
@@ -2443,13 +2544,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onPutFileResponse((PutFileResponse)msg);
+ _proxyListener.onPutFileResponse(msg);
onRPCResponseReceived(msg);
notifyPutFileStreamResponse(msg);
}
});
} else {
- _proxyListener.onPutFileResponse((PutFileResponse)msg);
+ _proxyListener.onPutFileResponse(msg);
onRPCResponseReceived(msg);
notifyPutFileStreamResponse(msg);
}
@@ -2461,12 +2562,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onDeleteFileResponse((DeleteFileResponse)msg);
+ _proxyListener.onDeleteFileResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onDeleteFileResponse((DeleteFileResponse)msg);
+ _proxyListener.onDeleteFileResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.LIST_FILES.toString())) {
@@ -2477,12 +2578,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onListFilesResponse((ListFilesResponse)msg);
+ _proxyListener.onListFilesResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onListFilesResponse((ListFilesResponse)msg);
+ _proxyListener.onListFilesResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SET_APP_ICON.toString())) {
@@ -2493,12 +2594,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSetAppIconResponse((SetAppIconResponse)msg);
+ _proxyListener.onSetAppIconResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSetAppIconResponse((SetAppIconResponse)msg);
+ _proxyListener.onSetAppIconResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SCROLLABLE_MESSAGE.toString())) {
@@ -2509,12 +2610,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onScrollableMessageResponse((ScrollableMessageResponse)msg);
+ _proxyListener.onScrollableMessageResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onScrollableMessageResponse((ScrollableMessageResponse)msg);
+ _proxyListener.onScrollableMessageResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.CHANGE_REGISTRATION.toString())) {
@@ -2525,12 +2626,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onChangeRegistrationResponse((ChangeRegistrationResponse)msg);
+ _proxyListener.onChangeRegistrationResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onChangeRegistrationResponse((ChangeRegistrationResponse)msg);
+ _proxyListener.onChangeRegistrationResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SET_DISPLAY_LAYOUT.toString())) {
@@ -2550,12 +2651,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSetDisplayLayoutResponse((SetDisplayLayoutResponse)msg);
+ _proxyListener.onSetDisplayLayoutResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSetDisplayLayoutResponse((SetDisplayLayoutResponse)msg);
+ _proxyListener.onSetDisplayLayoutResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.PERFORM_AUDIO_PASS_THRU.toString())) {
@@ -2566,12 +2667,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onPerformAudioPassThruResponse((PerformAudioPassThruResponse)msg);
+ _proxyListener.onPerformAudioPassThruResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onPerformAudioPassThruResponse((PerformAudioPassThruResponse)msg);
+ _proxyListener.onPerformAudioPassThruResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.END_AUDIO_PASS_THRU.toString())) {
@@ -2582,12 +2683,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onEndAudioPassThruResponse((EndAudioPassThruResponse)msg);
+ _proxyListener.onEndAudioPassThruResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onEndAudioPassThruResponse((EndAudioPassThruResponse)msg);
+ _proxyListener.onEndAudioPassThruResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SUBSCRIBE_VEHICLE_DATA.toString())) {
@@ -2598,12 +2699,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSubscribeVehicleDataResponse((SubscribeVehicleDataResponse)msg);
+ _proxyListener.onSubscribeVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSubscribeVehicleDataResponse((SubscribeVehicleDataResponse)msg);
+ _proxyListener.onSubscribeVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.UNSUBSCRIBE_VEHICLE_DATA.toString())) {
@@ -2614,12 +2715,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onUnsubscribeVehicleDataResponse((UnsubscribeVehicleDataResponse)msg);
+ _proxyListener.onUnsubscribeVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onUnsubscribeVehicleDataResponse((UnsubscribeVehicleDataResponse)msg);
+ _proxyListener.onUnsubscribeVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.GET_VEHICLE_DATA.toString())) {
@@ -2630,12 +2731,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onGetVehicleDataResponse((GetVehicleDataResponse)msg);
+ _proxyListener.onGetVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onGetVehicleDataResponse((GetVehicleDataResponse)msg);
+ _proxyListener.onGetVehicleDataResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.SUBSCRIBE_WAY_POINTS.toString())) {
@@ -2646,12 +2747,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSubscribeWayPointsResponse((SubscribeWayPointsResponse)msg);
+ _proxyListener.onSubscribeWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSubscribeWayPointsResponse((SubscribeWayPointsResponse)msg);
+ _proxyListener.onSubscribeWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.UNSUBSCRIBE_WAY_POINTS.toString())) {
@@ -2662,12 +2763,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onUnsubscribeWayPointsResponse((UnsubscribeWayPointsResponse)msg);
+ _proxyListener.onUnsubscribeWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onUnsubscribeWayPointsResponse((UnsubscribeWayPointsResponse)msg);
+ _proxyListener.onUnsubscribeWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.GET_WAY_POINTS.toString())) {
@@ -2678,12 +2779,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onGetWayPointsResponse((GetWayPointsResponse)msg);
+ _proxyListener.onGetWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onGetWayPointsResponse((GetWayPointsResponse)msg);
+ _proxyListener.onGetWayPointsResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.READ_DID.toString())) {
@@ -2693,12 +2794,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onReadDIDResponse((ReadDIDResponse)msg);
+ _proxyListener.onReadDIDResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onReadDIDResponse((ReadDIDResponse)msg);
+ _proxyListener.onReadDIDResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.GET_DTCS.toString())) {
@@ -2708,12 +2809,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onGetDTCsResponse((GetDTCsResponse)msg);
+ _proxyListener.onGetDTCsResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onGetDTCsResponse((GetDTCsResponse)msg);
+ _proxyListener.onGetDTCsResponse(msg);
onRPCResponseReceived(msg);
}
} else if (functionName.equals(FunctionID.DIAGNOSTIC_MESSAGE.toString())) {
@@ -2723,12 +2824,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onDiagnosticMessageResponse((DiagnosticMessageResponse)msg);
+ _proxyListener.onDiagnosticMessageResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onDiagnosticMessageResponse((DiagnosticMessageResponse)msg);
+ _proxyListener.onDiagnosticMessageResponse(msg);
onRPCResponseReceived(msg);
}
}
@@ -2740,12 +2841,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSystemRequestResponse((SystemRequestResponse)msg);
+ _proxyListener.onSystemRequestResponse(msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSystemRequestResponse((SystemRequestResponse)msg);
+ _proxyListener.onSystemRequestResponse(msg);
onRPCResponseReceived(msg);
}
}
@@ -2826,6 +2927,34 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_proxyListener.onUpdateTurnListResponse(msg);
onRPCResponseReceived(msg);
}
+ } else if (functionName.equals(FunctionID.SET_INTERIOR_VEHICLE_DATA.toString())) {
+ final SetInteriorVehicleDataResponse msg = new SetInteriorVehicleDataResponse(hash);
+ if (_callbackToUIThread) {
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onSetInteriorVehicleDataResponse(msg);
+ onRPCResponseReceived(msg);
+ }
+ });
+ } else {
+ _proxyListener.onSetInteriorVehicleDataResponse(msg);
+ onRPCResponseReceived(msg);
+ }
+ } else if (functionName.equals(FunctionID.GET_INTERIOR_VEHICLE_DATA.toString())) {
+ final GetInteriorVehicleDataResponse msg = new GetInteriorVehicleDataResponse(hash);
+ if (_callbackToUIThread) {
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onGetInteriorVehicleDataResponse(msg);
+ onRPCResponseReceived(msg);
+ }
+ });
+ } else {
+ _proxyListener.onGetInteriorVehicleDataResponse(msg);
+ onRPCResponseReceived(msg);
+ }
} else if (functionName.equals(FunctionID.GET_SYSTEM_CAPABILITY.toString())) {
// GetSystemCapabilityResponse
final GetSystemCapabilityResponse msg = new GetSystemCapabilityResponse(hash);
@@ -2841,29 +2970,42 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_proxyListener.onGetSystemCapabilityResponse(msg);
onRPCResponseReceived(msg);
}
- }
- else if (functionName.equals(FunctionID.SEND_HAPTIC_DATA.toString())) {
+ } else if (functionName.equals(FunctionID.BUTTON_PRESS.toString())) {
+ final ButtonPressResponse msg = new ButtonPressResponse(hash);
+ if (_callbackToUIThread) {
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onButtonPressResponse(msg);
+ onRPCResponseReceived(msg);
+ }
+ });
+ } else {
+ _proxyListener.onButtonPressResponse(msg);
+ onRPCResponseReceived(msg);
+ }
+ } else if (functionName.equals(FunctionID.SEND_HAPTIC_DATA.toString())) {
final SendHapticDataResponse msg = new SendHapticDataResponse(hash);
if (_callbackToUIThread) {
// Run in UI thread
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onSendHapticDataResponse((SendHapticDataResponse) msg);
+ _proxyListener.onSendHapticDataResponse( msg);
onRPCResponseReceived(msg);
}
});
} else {
- _proxyListener.onSendHapticDataResponse((SendHapticDataResponse) msg);
+ _proxyListener.onSendHapticDataResponse( msg);
onRPCResponseReceived(msg);
}
}
else {
if (_sdlMsgVersion != null) {
- DebugTool.logError("Unrecognized response Message: " + functionName.toString() +
+ DebugTool.logError("Unrecognized response Message: " + functionName +
" SDL Message Version = " + _sdlMsgVersion);
} else {
- DebugTool.logError("Unrecognized response Message: " + functionName.toString());
+ DebugTool.logError("Unrecognized response Message: " + functionName);
}
} // end-if
@@ -2880,22 +3022,25 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
sdlSession.getLockScreenMan().setHMILevel(msg.getHmiLevel());
}
- msg.setFirstRun(Boolean.valueOf(firstTimeFull));
+ msg.setFirstRun(firstTimeFull);
if (msg.getHmiLevel() == HMILevel.HMI_FULL) firstTimeFull = false;
- if (msg.getHmiLevel() != _priorHmiLevel && msg.getAudioStreamingState() != _priorAudioStreamingState) {
+ if (msg.getHmiLevel() != _hmiLevel || msg.getAudioStreamingState() != _audioStreamingState) {
+ _hmiLevel = msg.getHmiLevel();
+ _audioStreamingState = msg.getAudioStreamingState();
+
if (_callbackToUIThread) {
// Run in UI thread
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnHMIStatus((OnHMIStatus)msg);
+ _proxyListener.onOnHMIStatus(msg);
_proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnHMIStatus((OnHMIStatus)msg);
+ _proxyListener.onOnHMIStatus(msg);
_proxyListener.onOnLockScreenNotification(sdlSession.getLockScreenMan().getLockObj());
onRPCNotificationReceived(msg);
}
@@ -2909,12 +3054,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnCommand((OnCommand)msg);
+ _proxyListener.onOnCommand(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnCommand((OnCommand)msg);
+ _proxyListener.onOnCommand(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_DRIVER_DISTRACTION.toString())) {
@@ -2926,12 +3071,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
if (sdlSession != null)
{
DriverDistractionState drDist = msg.getState();
- boolean bVal = false;
- if (drDist == DriverDistractionState.DD_ON)
- bVal = true;
- else
- bVal = false;
- sdlSession.getLockScreenMan().setDriverDistStatus(bVal);
+ sdlSession.getLockScreenMan().setDriverDistStatus(drDist == DriverDistractionState.DD_ON);
}
if (_callbackToUIThread) {
@@ -3035,12 +3175,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnButtonPress((OnButtonPress)msg);
+ _proxyListener.onOnButtonPress(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnButtonPress((OnButtonPress)msg);
+ _proxyListener.onOnButtonPress(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_BUTTON_EVENT.toString())) {
@@ -3052,12 +3192,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnButtonEvent((OnButtonEvent)msg);
+ _proxyListener.onOnButtonEvent(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnButtonEvent((OnButtonEvent)msg);
+ _proxyListener.onOnButtonEvent(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_LANGUAGE_CHANGE.toString())) {
@@ -3069,12 +3209,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnLanguageChange((OnLanguageChange)msg);
+ _proxyListener.onOnLanguageChange(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnLanguageChange((OnLanguageChange)msg);
+ _proxyListener.onOnLanguageChange(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_HASH_CHANGE.toString())) {
@@ -3086,7 +3226,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnHashChange((OnHashChange)msg);
+ _proxyListener.onOnHashChange(msg);
onRPCNotificationReceived(msg);
if (_bAppResumeEnabled)
{
@@ -3095,7 +3235,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
});
} else {
- _proxyListener.onOnHashChange((OnHashChange)msg);
+ _proxyListener.onOnHashChange(msg);
onRPCNotificationReceived(msg);
if (_bAppResumeEnabled)
{
@@ -3131,12 +3271,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnSystemRequest((OnSystemRequest)msg);
+ _proxyListener.onOnSystemRequest(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnSystemRequest((OnSystemRequest)msg);
+ _proxyListener.onOnSystemRequest(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_AUDIO_PASS_THRU.toString())) {
@@ -3147,12 +3287,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnAudioPassThru((OnAudioPassThru)msg);
+ _proxyListener.onOnAudioPassThru(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnAudioPassThru((OnAudioPassThru)msg);
+ _proxyListener.onOnAudioPassThru(msg);
onRPCNotificationReceived(msg);
}
} else if (functionName.equals(FunctionID.ON_VEHICLE_DATA.toString())) {
@@ -3163,12 +3303,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnVehicleData((OnVehicleData)msg);
+ _proxyListener.onOnVehicleData(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnVehicleData((OnVehicleData)msg);
+ _proxyListener.onOnVehicleData(msg);
onRPCNotificationReceived(msg);
}
}
@@ -3215,12 +3355,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnKeyboardInput((OnKeyboardInput)msg);
+ _proxyListener.onOnKeyboardInput(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnKeyboardInput((OnKeyboardInput)msg);
+ _proxyListener.onOnKeyboardInput(msg);
onRPCNotificationReceived(msg);
}
}
@@ -3231,12 +3371,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnTouchEvent((OnTouchEvent)msg);
+ _proxyListener.onOnTouchEvent(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnTouchEvent((OnTouchEvent)msg);
+ _proxyListener.onOnTouchEvent(msg);
onRPCNotificationReceived(msg);
}
}
@@ -3247,21 +3387,37 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_mainUIHandler.post(new Runnable() {
@Override
public void run() {
- _proxyListener.onOnWayPointChange((OnWayPointChange)msg);
+ _proxyListener.onOnWayPointChange(msg);
+ onRPCNotificationReceived(msg);
+ }
+ });
+ } else {
+ _proxyListener.onOnWayPointChange(msg);
+ onRPCNotificationReceived(msg);
+ }
+ }
+ else if (functionName.equals(FunctionID.ON_INTERIOR_VEHICLE_DATA.toString())) {
+ final OnInteriorVehicleData msg = new OnInteriorVehicleData(hash);
+ if (_callbackToUIThread) {
+ // Run in UI thread
+ _mainUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ _proxyListener.onOnInteriorVehicleData(msg);
onRPCNotificationReceived(msg);
}
});
} else {
- _proxyListener.onOnWayPointChange((OnWayPointChange)msg);
+ _proxyListener.onOnInteriorVehicleData(msg);
onRPCNotificationReceived(msg);
}
}
else {
if (_sdlMsgVersion != null) {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName.toString() +
+ DebugTool.logInfo("Unrecognized notification Message: " + functionName +
" connected to SDL using message version: " + _sdlMsgVersion.getMajorVersion() + "." + _sdlMsgVersion.getMinorVersion());
} else {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName.toString());
+ DebugTool.logInfo("Unrecognized notification Message: " + functionName);
}
} // end-if
} // end-if notification
@@ -3272,8 +3428,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Takes an RPCRequest and sends it to SDL. Responses are captured through callback on IProxyListener.
*
- * @param request
- * @throws SdlException
+ * @param request is the RPCRequest being sent
+ * @throws SdlException if an unrecoverable error is encountered if an unrecoverable error is encountered
*/
public void sendRPCRequest(RPCRequest request) throws SdlException {
if (_proxyDisposed) {
@@ -3290,7 +3446,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
// Test if SdlConnection is null
synchronized(CONNECTION_REFERENCE_LOCK) {
- if (sdlSession == null || !sdlSession.getIsConnected()) {
+ if (!getIsConnected()) {
SdlTrace.logProxyEvent("Application attempted to send and RPCRequest without a connected transport.", SDL_LIB_TRACE_KEY);
throw new SdlException("There is no valid connection to SDL. sendRPCRequest cannot be called until SDL has been connected.", SdlExceptionCause.SDL_UNAVAILABLE);
}
@@ -3336,7 +3492,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
queueInternalMessage(message);
}
- private void startRPCProtocolSession(byte sessionID, String correlationID) {
+ private void startRPCProtocolSession() {
// Set Proxy Lifecyclek Available
if (_advancedLifecycleManagementEnabled) {
@@ -3353,7 +3509,6 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_hmiDisplayLanguageDesired,
_appType,
_appID,
- _autoActivateIdDesired,
REGISTER_APP_INTERFACE_CORRELATION_ID);
} catch (Exception e) {
@@ -3442,15 +3597,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
try {
StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, wiproVersion, lSize, sdlSession);
rpcPacketizer.start();
- RPCStreamController streamController = new RPCStreamController(rpcPacketizer, request.getCorrelationID());
- return streamController;
+ return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
} catch (Exception e) {
Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
return null;
}
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "UnusedReturnValue"})
private RPCStreamController startRPCStream(InputStream is, PutFile request, SessionType sType, byte rpcSessionID, byte wiproVersion)
{
if (sdlSession == null) return null;
@@ -3464,8 +3618,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
try {
StreamRPCPacketizer rpcPacketizer = new StreamRPCPacketizer((SdlProxyBase<IProxyListenerBase>) this, sdlSession, is, request, sType, rpcSessionID, wiproVersion, lSize, sdlSession);
rpcPacketizer.start();
- RPCStreamController streamController = new RPCStreamController(rpcPacketizer, request.getCorrelationID());
- return streamController;
+ return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
} catch (Exception e) {
Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
return null;
@@ -3480,10 +3633,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
private RPCStreamController startPutFileStream(InputStream is, PutFile msg) {
if (sdlSession == null) return null;
if (is == null) return null;
- startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), _wiproVersion);
- return null;
+ return startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), _wiproVersion);
}
+ @SuppressWarnings("UnusedReturnValue")
public boolean startRPCStream(InputStream is, RPCRequest msg) {
if (sdlSession == null) return false;
sdlSession.startRPCStream(is, msg, SessionType.RPC, sdlSession.getSessionId(), _wiproVersion);
@@ -3501,7 +3654,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
private class CallableMethod implements Callable<Void> {
- private long waitTime;
+
+ private final long waitTime;
public CallableMethod(int timeInMillis){
this.waitTime=timeInMillis;
@@ -3542,12 +3696,23 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Opens the video service (serviceType 11) and subsequently streams raw H264 video from an InputStream provided by the app
*@return true if service is opened successfully and stream is started, return false otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public boolean startH264(InputStream is, boolean isEncrypted) {
if (sdlSession == null) return false;
navServiceStartResponseReceived = false;
navServiceStartResponse = false;
+ navServiceStartRejectedParams = null;
+
+ // When startH264() API is used, we will not send video format / width / height information
+ // with StartService. (Reasons: InputStream does not provide timestamp information so RTP
+ // cannot be used. startH264() does not provide with/height information.)
+ VideoStreamingParameters emptyParam = new VideoStreamingParameters();
+ emptyParam.setResolution(null);
+ emptyParam.setFormat(null);
+ sdlSession.setDesiredVideoParams(emptyParam);
sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
@@ -3555,10 +3720,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
ScheduledExecutorService scheduler = createScheduler();
scheduler.execute(fTask);
+ //noinspection StatementWithEmptyBody
while (!navServiceStartResponseReceived && !fTask.isDone());
scheduler.shutdown();
- scheduler = null;
- fTask = null;
if (navServiceStartResponse) {
try {
@@ -3576,22 +3740,33 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Opens the video service (serviceType 11) and subsequently provides an OutputStream to the app to use for a raw H264 video stream
*@return OutputStream if service is opened successfully and stream is started, return null otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public OutputStream startH264(boolean isEncrypted) {
if (sdlSession == null) return null;
navServiceStartResponseReceived = false;
navServiceStartResponse = false;
+ navServiceStartRejectedParams = null;
+
+ // When startH264() API is used, we will not send video format / width / height information
+ // with StartService. (Reasons: OutputStream does not provide timestamp information so RTP
+ // cannot be used. startH264() does not provide with/height information.)
+ VideoStreamingParameters emptyParam = new VideoStreamingParameters();
+ emptyParam.setResolution(null);
+ emptyParam.setFormat(null);
+ sdlSession.setDesiredVideoParams(emptyParam);
+
sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
ScheduledExecutorService scheduler = createScheduler();
scheduler.execute(fTask);
+ //noinspection StatementWithEmptyBody
while (!navServiceStartResponseReceived && !fTask.isDone());
scheduler.shutdown();
- scheduler = null;
- fTask = null;
if (navServiceStartResponse) {
try {
@@ -3608,66 +3783,49 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Closes the opened video service (serviceType 11)
*@return true if the video service is closed successfully, return false otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public boolean endH264() {
- if (sdlSession == null) return false;
-
- navServiceEndResponseReceived = false;
- navServiceEndResponse = false;
- sdlSession.stopVideoStream();
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- while (!navServiceEndResponseReceived && !fTask.isDone());
- scheduler.shutdown();
- scheduler = null;
- fTask = null;
-
- if (navServiceEndResponse) {
- return true;
- } else {
- return false;
- }
+ return endVideoStream();
}
/**
*Pauses the stream for the opened audio service (serviceType 10)
*@return true if the audio service stream is paused successfully, return false otherwise
*/
- public boolean pausePCM()
- {
- if (sdlSession == null) return false;
- return sdlSession.pauseAudioStream();
+ @SuppressWarnings("unused")
+ @Deprecated
+ public boolean pausePCM() {
+ return pauseAudioStream();
}
/**
*Pauses the stream for the opened video service (serviceType 11)
*@return true if the video service stream is paused successfully, return false otherwise
*/
- public boolean pauseH264()
- {
- if (sdlSession == null) return false;
- return sdlSession.pauseVideoStream();
+ @SuppressWarnings("unused")
+ @Deprecated
+ public boolean pauseH264() {
+ return pauseVideoStream();
}
/**
*Resumes the stream for the opened audio service (serviceType 10)
*@return true if the audio service stream is resumed successfully, return false otherwise
*/
- public boolean resumePCM()
- {
- if (sdlSession == null) return false;
- return sdlSession.resumeAudioStream();
+ @SuppressWarnings("unused")
+ @Deprecated
+ public boolean resumePCM() {
+ return resumeAudioStream();
}
/**
*Resumes the stream for the opened video service (serviceType 11)
*@return true if the video service is resumed successfully, return false otherwise
*/
- public boolean resumeH264()
- {
- if (sdlSession == null) return false;
- return sdlSession.resumeVideoStream();
+ @SuppressWarnings("unused")
+ @Deprecated
+ public boolean resumeH264() {
+ return resumeVideoStream();
}
@@ -3675,6 +3833,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Opens the audio service (serviceType 10) and subsequently streams raw PCM audio from an InputStream provided by the app
*@return true if service is opened successfully and stream is started, return false otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public boolean startPCM(InputStream is, boolean isEncrypted) {
if (sdlSession == null) return false;
@@ -3686,10 +3846,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
ScheduledExecutorService scheduler = createScheduler();
scheduler.execute(fTask);
+ //noinspection StatementWithEmptyBody
while (!pcmServiceStartResponseReceived && !fTask.isDone());
scheduler.shutdown();
- scheduler = null;
- fTask = null;
if (pcmServiceStartResponse) {
try {
@@ -3707,6 +3866,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Opens the audio service (serviceType 10) and subsequently provides an OutputStream to the app
*@return OutputStream if service is opened successfully and stream is started, return null otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public OutputStream startPCM(boolean isEncrypted) {
if (sdlSession == null) return null;
@@ -3718,10 +3879,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
ScheduledExecutorService scheduler = createScheduler();
scheduler.execute(fTask);
+ //noinspection StatementWithEmptyBody
while (!pcmServiceStartResponseReceived && !fTask.isDone());
scheduler.shutdown();
- scheduler = null;
- fTask = null;
if (pcmServiceStartResponse) {
try {
@@ -3730,6 +3890,19 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
return null;
}
} else {
+ if (pcmServiceStartRejectedParams != null) {
+ StringBuilder builder = new StringBuilder();
+ for (String paramName : pcmServiceStartRejectedParams) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(paramName);
+ }
+ DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
+
+ } else {
+ DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
+ }
return null;
}
}
@@ -3738,31 +3911,88 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*Closes the opened audio service (serviceType 10)
*@return true if the audio service is closed successfully, return false otherwise
*/
+ @SuppressWarnings("unused")
+ @Deprecated
public boolean endPCM() {
- if (sdlSession == null) return false;
- SdlConnection sdlConn = sdlSession.getSdlConnection();
- if (sdlConn == null) return false;
-
- pcmServiceEndResponseReceived = false;
- pcmServiceEndResponse = false;
- sdlSession.stopAudioStream();
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
+ return endAudioStream();
+ }
+
+ /**
+ * Opens a video service (service type 11) and subsequently provides an IVideoStreamListener
+ * to the app to send video data.
+ *
+ * @param isEncrypted Specify true if packets on this service have to be encrypted
+ * @param codec Video codec which will be used for streaming. Currently, only
+ * VideoStreamingCodec.H264 is accepted.
+ * @param width Width of the video in pixels
+ * @param height Height of the video in pixels
+ *
+ * @return IVideoStreamListener interface if service is opened successfully and streaming is
+ * started, null otherwise
+ */
+ @SuppressWarnings("unused")
+ public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingCodec codec,
+ int width, int height) {
+ if (sdlSession == null) {
+ DebugTool.logWarning("SdlSession is not created yet.");
+ return null;
+ }
+ if (sdlSession.getSdlConnection() == null) {
+ DebugTool.logWarning("SdlConnection is not available.");
+ return null;
+ }
- while (!pcmServiceEndResponseReceived && !fTask.isDone());
- scheduler.shutdown();
- scheduler = null;
- fTask = null;
+ VideoStreamingCodec[] codecs = {codec};
+ VideoStreamingParameters acceptedParams = tryStartVideoStream(codecs, width, height, -1, -1,
+ -1, isEncrypted);
+ if (acceptedParams != null) {
+ return sdlSession.startVideoStream();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ *Closes the opened video service (serviceType 11)
+ *@return true if the video service is closed successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean endVideoStream() {
+ if (sdlSession == null) return false;
+
+ navServiceEndResponseReceived = false;
+ navServiceEndResponse = false;
+ sdlSession.stopVideoStream();
+
+ FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
+ ScheduledExecutorService scheduler = createScheduler();
+ scheduler.execute(fTask);
+
+ //noinspection StatementWithEmptyBody
+ while (!navServiceEndResponseReceived && !fTask.isDone());
+ scheduler.shutdown();
+
+ return navServiceEndResponse;
+ }
+
+ /**
+ *Pauses the stream for the opened video service (serviceType 11)
+ *@return true if the video service stream is paused successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean pauseVideoStream() {
+ return sdlSession != null && sdlSession.pauseVideoStream();
+ }
+
+ /**
+ *Resumes the stream for the opened video service (serviceType 11)
+ *@return true if the video service is resumed successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean resumeVideoStream() {
+ return sdlSession != null && sdlSession.resumeVideoStream();
+ }
- if (pcmServiceEndResponse) {
- return true;
- } else {
- return false;
- }
- }
-
/**
* Opens the video service (serviceType 11) and creates a Surface (used for streaming video) with input parameters provided by the app
* @param frameRate - specified rate of frames to utilize for creation of Surface
@@ -3772,38 +4002,196 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param bitrate - specified bitrate to utilize for creation of Surface
*@return Surface if service is opened successfully and stream is started, return null otherwise
*/
- public Surface createOpenGLInputSurface(int frameRate, int iFrameInterval, int width,
- int height, int bitrate, boolean isEncrypted) {
+ @SuppressWarnings("unused")
+ public Surface createOpenGLInputSurface(int frameRate, int iFrameInterval, int width,
+ int height, int bitrate, boolean isEncrypted) {
if (sdlSession == null) return null;
SdlConnection sdlConn = sdlSession.getSdlConnection();
if (sdlConn == null) return null;
-
- navServiceStartResponseReceived = false;
- navServiceStartResponse = false;
- sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
-
- FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
- ScheduledExecutorService scheduler = createScheduler();
- scheduler.execute(fTask);
-
- while (!navServiceStartResponseReceived && !fTask.isDone());
- scheduler.shutdown();
- scheduler = null;
- fTask = null;
-
- if (navServiceStartResponse) {
+
+ VideoStreamingCodec[] codecs = {VideoStreamingCodec.H264};
+ VideoStreamingParameters acceptedParams = tryStartVideoStream(codecs, width, height, bitrate,
+ frameRate, iFrameInterval, isEncrypted);
+ if (acceptedParams != null) {
return sdlSession.createOpenGLInputSurface(frameRate, iFrameInterval, width,
- height, bitrate, SessionType.NAV, sdlSession.getSessionId());
+ height, bitrate, SessionType.NAV, sdlSession.getSessionId());
} else {
return null;
}
}
-
+
+ /**
+ * Try to open a video service by trying all available codec/protocols one by one.
+ *
+ * Only information from codecs, width and height are used during video format negotiation.
+ *
+ * @param codecs List of video codecs which app or proxy would like to use
+ * @param width Width of the video in pixels
+ * @param height Height of the video in pixels
+ * @param bitrate Specified bitrate of the video
+ * @param frameRate Specified rate of frames
+ * @param iFrameInterval Specified interval
+ * @param isEncrypted Specify true if packets on this service have to be encrypted
+ *
+ * @return If the service is opened successfully, an instance of VideoStreamingParams is
+ * returned which contains accepted video format. If the service is opened with legacy
+ * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is
+ * returned, but its video format and resolution are null.
+ * If the service was not opened then null is returned.
+ */
+ @SuppressWarnings("unused")
+ private VideoStreamingParameters tryStartVideoStream(VideoStreamingCodec[] codecs,
+ int width, int height,
+ int bitrate, int frameRate, int iFrameInterval,
+ boolean isEncrypted) {
+ if (sdlSession == null) {
+ DebugTool.logWarning("SdlSession is not created yet.");
+ return null;
+ }
+ if (codecs == null || codecs.length == 0) {
+ DebugTool.logWarning("Video codec list is not supplied.");
+ return null;
+ }
+
+ List<VideoStreamingFormat> availableFormats = new ArrayList<>();
+ for (VideoStreamingCodec codec : codecs) {
+ if (codec == VideoStreamingCodec.H264) {
+ availableFormats.add(VIDEO_STREAMING_FORMAT_H264_RTP);
+ availableFormats.add(VIDEO_STREAMING_FORMAT_H264_RAW);
+ } else {
+ DebugTool.logInfo("Video codec " + codec +" is not supported.");
+ }
+ }
+
+ VideoStreamingCapability videoStreamingCapabilities = null;
+ if (_systemCapabilityManager != null) {
+ videoStreamingCapabilities = (VideoStreamingCapability) _systemCapabilityManager.getCapability(
+ SystemCapabilityType.VIDEO_STREAMING);
+ }
+
+ List<VideoStreamingParameters> desiredParamsList = createDesiredVideoParams(
+ videoStreamingCapabilities, frameRate, iFrameInterval, width, height, bitrate,
+ availableFormats.toArray(new VideoStreamingFormat[0]));
+
+ // If none of video formats are accepted then try StartService without parameter at last.
+ // This also applies to the case where the system is legacy and capability isn't available.
+ VideoStreamingParameters emptyParam = new VideoStreamingParameters();
+ emptyParam.setResolution(null);
+ emptyParam.setFormat(null);
+ desiredParamsList.add(emptyParam);
+
+ for (VideoStreamingParameters params : desiredParamsList) {
+ sdlSession.setDesiredVideoParams(params);
+
+ navServiceStartResponseReceived = false;
+ navServiceStartResponse = false;
+ navServiceStartRejectedParams = null;
+
+ sdlSession.startService(SessionType.NAV, sdlSession.getSessionId(), isEncrypted);
+
+ FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
+ ScheduledExecutorService scheduler = createScheduler();
+ scheduler.execute(fTask);
+
+ //noinspection StatementWithEmptyBody
+ while (!navServiceStartResponseReceived && !fTask.isDone());
+ scheduler.shutdown();
+
+ if (navServiceStartResponse) {
+ if (!params.equals(emptyParam)) {
+ DebugTool.logInfo("StartService for nav succeeded with params: " + params);
+ } else {
+ DebugTool.logInfo("StartService for nav succeeded in legacy mode.");
+ }
+ return params;
+ }
+
+ if (navServiceStartRejectedParams != null) {
+ StringBuilder builder = new StringBuilder();
+ for (String paramName : navServiceStartRejectedParams) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(paramName);
+ }
+ DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
+
+ if (!navServiceStartRejectedParams.contains(ControlFrameTags.Video.StartService.VIDEO_PROTOCOL)
+ && !navServiceStartRejectedParams.contains(ControlFrameTags.Video.StartService.VIDEO_CODEC)) {
+ // The reason of NACK is not protocol nor codec. There is no point retrying with
+ // another video format, so we simply fail here.
+ break;
+ }
+ } else {
+ DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates a list of VideoStreamingParams with video formats that are supported by both HMI and proxy
+ *
+ * Note: this method does not take care of matching video resolution. App should look into
+ * HMI capability's preferredResolution and adjust width and height accordingly.
+ *
+ * @param hmiCapability HMI's capability information
+ * @param frameRate specified rate of frames
+ * @param frameInterval specified interval
+ * @param width specified width of the video
+ * @param height specified height of the video
+ * @param bitrate specified bitrate of the video
+ * @param availableFormats list of video formats supported by proxy
+ * @return list of VideoStreamingParams instance. This list can be empty.
+ */
+ private static List<VideoStreamingParameters> createDesiredVideoParams(
+ VideoStreamingCapability hmiCapability,
+ int frameRate, int frameInterval, int width, int height, int bitrate,
+ VideoStreamingFormat[] availableFormats) {
+ ArrayList<VideoStreamingFormat> formats = new ArrayList<>();
+ if (hmiCapability != null && hmiCapability.getSupportedFormats() != null
+ && availableFormats != null) {
+ // supportedFormat is listed in HMI's preferred order
+ for (VideoStreamingFormat supportedFormat : hmiCapability.getSupportedFormats()) {
+ for (VideoStreamingFormat availableFormat : availableFormats) {
+ if (supportedFormat.getProtocol() == availableFormat.getProtocol()
+ && supportedFormat.getCodec() == availableFormat.getCodec()) {
+ formats.add(supportedFormat);
+ break;
+ }
+ }
+ }
+ }
+
+ ArrayList<VideoStreamingParameters> list = new ArrayList<>();
+ for (VideoStreamingFormat format : formats) {
+ VideoStreamingParameters params = new VideoStreamingParameters();
+ ImageResolution resolution = new ImageResolution();
+ resolution.setResolutionWidth(width);
+ resolution.setResolutionHeight(height);
+ params.setResolution(resolution);
+ if (frameRate >= 0) {
+ params.setFrameRate(frameRate);
+ }
+ if (bitrate >= 0) {
+ params.setBitrate(bitrate);
+ }
+ if (frameInterval >= 0) {
+ params.setInterval(frameInterval);
+ }
+ params.setFormat(format);
+ list.add(params);
+ }
+
+ return list;
+ }
+
/**
*Starts the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
*/
- public void startEncoder () {
+ @SuppressWarnings("unused")
+ public void startEncoder () {
if (sdlSession == null) return;
SdlConnection sdlConn = sdlSession.getSdlConnection();
if (sdlConn == null) return;
@@ -3814,7 +4202,8 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
*Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
*/
- public void releaseEncoder() {
+ @SuppressWarnings("unused")
+ public void releaseEncoder() {
if (sdlSession == null) return;
SdlConnection sdlConn = sdlSession.getSdlConnection();
if (sdlConn == null) return;
@@ -3825,22 +4214,134 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
*Releases the MediaCodec encoder utilized in conjunction with the Surface returned via the createOpenGLInputSurface method
*/
- public void drainEncoder(boolean endOfStream) {
+ @SuppressWarnings("unused")
+ public void drainEncoder(boolean endOfStream) {
if (sdlSession == null) return;
SdlConnection sdlConn = sdlSession.getSdlConnection();
if (sdlConn == null) return;
sdlSession.drainEncoder(endOfStream);
}
-
+
+ /**
+ * Opens a audio service (service type 10) and subsequently provides an IAudioStreamListener
+ * to the app to send audio data.
+ *
+ * Currently information passed by "params" are ignored, since Audio Streaming feature lacks
+ * capability negotiation mechanism. App should configure audio stream data to align with
+ * head unit's capability by checking (upcoming) pcmCapabilities. The default format is in
+ * 16kHz and 16 bits.
+ *
+ * @param isEncrypted Specify true if packets on this service have to be encrypted
+ * @param codec Audio codec which will be used for streaming. Currently, only
+ * AudioStreamingCodec.LPCM is accepted.
+ * @param params (Reserved for future use) Additional configuration information for each
+ * codec. If "codec" is AudioStreamingCodec.LPCM, "params" must be an
+ * instance of LPCMParams class.
+ *
+ * @return IAudioStreamListener interface if service is opened successfully and streaming is
+ * started, null otherwise
+ */
+ @SuppressWarnings("unused")
+ public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec,
+ AudioStreamingParams params) {
+ if (sdlSession == null) {
+ DebugTool.logWarning("SdlSession is not created yet.");
+ return null;
+ }
+ if (sdlSession.getSdlConnection() == null) {
+ DebugTool.logWarning("SdlConnection is not available.");
+ return null;
+ }
+ if (codec != AudioStreamingCodec.LPCM) {
+ DebugTool.logWarning("Audio codec " + codec + " is not supported.");
+ return null;
+ }
+
+ pcmServiceStartResponseReceived = false;
+ pcmServiceStartResponse = false;
+ sdlSession.startService(SessionType.PCM, sdlSession.getSessionId(), isEncrypted);
+
+ FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
+ ScheduledExecutorService scheduler = createScheduler();
+ scheduler.execute(fTask);
+
+ //noinspection StatementWithEmptyBody
+ while (!pcmServiceStartResponseReceived && !fTask.isDone());
+ scheduler.shutdown();
+
+ if (pcmServiceStartResponse) {
+ DebugTool.logInfo("StartService for audio succeeded");
+ return sdlSession.startAudioStream();
+ } else {
+ if (pcmServiceStartRejectedParams != null) {
+ StringBuilder builder = new StringBuilder();
+ for (String paramName : pcmServiceStartRejectedParams) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(paramName);
+ }
+ DebugTool.logWarning("StartService for audio failed. Rejected params: " + builder.toString());
+ } else {
+ DebugTool.logWarning("StartService for audio failed (rejected params not supplied)");
+ }
+ return null;
+ }
+ }
+
+ /**
+ *Closes the opened audio service (serviceType 10)
+ *@return true if the audio service is closed successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean endAudioStream() {
+ if (sdlSession == null) return false;
+ SdlConnection sdlConn = sdlSession.getSdlConnection();
+ if (sdlConn == null) return false;
+
+ pcmServiceEndResponseReceived = false;
+ pcmServiceEndResponse = false;
+ sdlSession.stopAudioStream();
+
+ FutureTask<Void> fTask = createFutureTask(new CallableMethod(RESPONSE_WAIT_TIME));
+ ScheduledExecutorService scheduler = createScheduler();
+ scheduler.execute(fTask);
+
+ //noinspection StatementWithEmptyBody
+ while (!pcmServiceEndResponseReceived && !fTask.isDone());
+ scheduler.shutdown();
+
+ return pcmServiceEndResponse;
+ }
+
+ /**
+ *Pauses the stream for the opened audio service (serviceType 10)
+ *@return true if the audio service stream is paused successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean pauseAudioStream() {
+ return sdlSession != null && sdlSession.pauseAudioStream();
+ }
+
+ /**
+ *Resumes the stream for the opened audio service (serviceType 10)
+ *@return true if the audio service stream is resumed successfully, return false otherwise
+ */
+ @SuppressWarnings("unused")
+ public boolean resumeAudioStream() {
+ return sdlSession != null && sdlSession.resumeAudioStream();
+ }
+
private void NavServiceStarted() {
navServiceStartResponseReceived = true;
navServiceStartResponse = true;
}
- private void NavServiceStartedNACK() {
+ private void NavServiceStartedNACK(List<String> rejectedParams) {
navServiceStartResponseReceived = true;
navServiceStartResponse = false;
+ navServiceStartRejectedParams = rejectedParams;
}
private void AudioServiceStarted() {
@@ -3852,9 +4353,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
rpcProtectedResponseReceived = true;
rpcProtectedStartResponse = true;
}
- private void AudioServiceStartedNACK() {
+ private void AudioServiceStartedNACK(List<String> rejectedParams) {
pcmServiceStartResponseReceived = true;
pcmServiceStartResponse = false;
+ pcmServiceStartRejectedParams = rejectedParams;
}
private void NavServiceEnded() {
@@ -3882,6 +4384,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
_appService = mService;
}
+ @SuppressWarnings("unused")
public boolean startProtectedRPCService() {
rpcProtectedResponseReceived = false;
rpcProtectedStartResponse = false;
@@ -3891,18 +4394,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
ScheduledExecutorService scheduler = createScheduler();
scheduler.execute(fTask);
+ //noinspection StatementWithEmptyBody
while (!rpcProtectedResponseReceived && !fTask.isDone());
scheduler.shutdown();
- scheduler = null;
- fTask = null;
- if (rpcProtectedStartResponse) {
- return true;
- } else {
- return false;
- }
- }
-
+ return rpcProtectedStartResponse;
+ }
+
+ @SuppressWarnings("unused")
public void getLockScreenIcon(final OnLockScreenIconDownloadedListener l){
if(lockScreenIconRequest == null){
l.onLockScreenIconDownloadError(new SdlException("This version of SDL core may not support lock screen icons.",
@@ -3923,7 +4422,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
}
- /******************** Public Helper Methods *************************/
+ /* ******************* Public Helper Methods *************************/
/*Begin V1 Enhanced helper*/
@@ -3938,11 +4437,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
*@param IconType -Describes whether the image is static or dynamic
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void addCommand(Integer commandID,
- String menuText, Integer parentID, Integer position,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
+ String menuText, Integer parentID, Integer position,
+ Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
throws SdlException {
AddCommand msg = RPCRequestFactory.buildAddCommand(commandID, menuText, parentID, position,
@@ -3961,11 +4461,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
*@param IconType -Describes whether the image is static or dynamic
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Integer position,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
+ String menuText, Integer position,
+ Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, position, vrCommands, IconValue, IconType, correlationID);
@@ -3980,11 +4481,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
*@param IconType -Describes whether the image is static or dynamic
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Integer position, String IconValue, ImageType IconType,
- Integer correlationID)
+ String menuText, Integer position, String IconValue, ImageType IconType,
+ Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, position, null, IconValue, IconType, correlationID);
@@ -3998,10 +4500,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
*@param IconType -Describes whether the image is static or dynamic
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, String IconValue, ImageType IconType, Integer correlationID)
+ String menuText, String IconValue, ImageType IconType, Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, null, null, IconValue, IconType, correlationID);
@@ -4016,10 +4519,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
* @param IconType -Describes whether the image is static or dynamic
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
+ String menuText, Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, null, vrCommands, IconValue, IconType, correlationID);
@@ -4033,10 +4537,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param IconValue -A static hex icon value or the binary image file name identifier (sent by the PutFile RPC).
* @param IconType -Describes whether the image is static or dynamic
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
+ Vector<String> vrCommands, String IconValue, ImageType IconType, Integer correlationID)
throws SdlException {
addCommand(commandID, null, null, null, vrCommands, IconValue, IconType, correlationID);
@@ -4053,11 +4558,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param position -Menu position for optional sub value containing menu parameters.
*@param vrCommands -VR synonyms for this AddCommand.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void addCommand(Integer commandID,
- String menuText, Integer parentID, Integer position,
- Vector<String> vrCommands, Integer correlationID)
+ String menuText, Integer parentID, Integer position,
+ Vector<String> vrCommands, Integer correlationID)
throws SdlException {
AddCommand msg = RPCRequestFactory.buildAddCommand(commandID, menuText, parentID, position,
@@ -4074,11 +4580,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param position -Menu position for optional sub value containing menu parameters.
*@param vrCommands -VR synonyms for this AddCommand.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Integer position,
- Vector<String> vrCommands, Integer correlationID)
+ String menuText, Integer position,
+ Vector<String> vrCommands, Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, position, vrCommands, correlationID);
@@ -4091,11 +4598,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param menuText -Menu text for optional sub value containing menu parameters.
*@param position -Menu position for optional sub value containing menu parameters.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Integer position,
- Integer correlationID)
+ String menuText, Integer position,
+ Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, position, null, correlationID);
@@ -4107,14 +4615,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param commandID -Unique command ID of the command to add.
*@param menuText -Menu text for optional sub value containing menu parameters.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Integer correlationID)
+ String menuText, Integer correlationID)
throws SdlException {
- Vector<String> vrCommands = null;
-
- addCommand(commandID, menuText, null, null, vrCommands, correlationID);
+ addCommand(commandID, menuText, null, null, (Vector<String>)null, correlationID);
}
/**
@@ -4124,10 +4631,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param menuText -Menu text for optional sub value containing menu parameters.
*@param vrCommands -VR synonyms for this AddCommand.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- String menuText, Vector<String> vrCommands, Integer correlationID)
+ String menuText, Vector<String> vrCommands, Integer correlationID)
throws SdlException {
addCommand(commandID, menuText, null, null, vrCommands, correlationID);
@@ -4139,10 +4647,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*@param commandID -Unique command ID of the command to add.
*@param vrCommands -VR synonyms for this AddCommand.
*@param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- *@throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addCommand(Integer commandID,
- Vector<String> vrCommands, Integer correlationID)
+ Vector<String> vrCommands, Integer correlationID)
throws SdlException {
addCommand(commandID, null, null, null, vrCommands, correlationID);
@@ -4156,10 +4665,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param menuName -Text to show in the menu for this sub menu.
* @param position -Position within the items that are are at top level of the in application menu.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void addSubMenu(Integer menuID, String menuName,
- Integer position, Integer correlationID)
+ Integer position, Integer correlationID)
throws SdlException {
AddSubMenu msg = RPCRequestFactory.buildAddSubMenu(menuID, menuName,
@@ -4174,10 +4684,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param menuID -Unique ID of the sub menu to add.
* @param menuName -Text to show in the menu for this sub menu.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void addSubMenu(Integer menuID, String menuName,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
addSubMenu(menuID, menuName, null, correlationID);
}
@@ -4194,11 +4705,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param duration -Timeout in milliseconds.
* @param softButtons -A list of App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void alert(String ttsText, String alertText1,
- String alertText2, String alertText3, Boolean playTone, Integer duration, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
+ String alertText2, String alertText3, Boolean playTone, Integer duration, Vector<SoftButton> softButtons,
+ Integer correlationID) throws SdlException {
Alert msg = RPCRequestFactory.buildAlert(ttsText, alertText1, alertText2, alertText3, playTone, duration, softButtons, correlationID);
@@ -4216,7 +4728,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param duration -Timeout in milliseconds.
* @param softButtons -A list of App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
public void alert(Vector<TTSChunk> ttsChunks,
String alertText1, String alertText2, String alertText3, Boolean playTone,
@@ -4234,10 +4746,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param playTone -Defines if tone should be played.
* @param softButtons -A list of App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(String ttsText, Boolean playTone, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
alert(ttsText, null, null, null, playTone, null, softButtons, correlationID);
}
@@ -4249,10 +4762,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param playTone -Defines if tone should be played.
* @param softButtons -A list of App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(Vector<TTSChunk> chunks, Boolean playTone, Vector<SoftButton> softButtons,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
alert(chunks, null, null, null, playTone, null, softButtons, correlationID);
}
@@ -4267,10 +4781,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param duration -Timeout in milliseconds.
* @param softButtons -A list of App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(String alertText1, String alertText2, String alertText3,
- Boolean playTone, Integer duration, Vector<SoftButton> softButtons, Integer correlationID)
+ Boolean playTone, Integer duration, Vector<SoftButton> softButtons, Integer correlationID)
throws SdlException {
alert((Vector<TTSChunk>)null, alertText1, alertText2, alertText3, playTone, duration, softButtons, correlationID);
@@ -4287,11 +4802,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param playTone -Defines if tone should be played.
* @param duration -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void alert(String ttsText, String alertText1,
- String alertText2, Boolean playTone, Integer duration,
- Integer correlationID) throws SdlException {
+ String alertText2, Boolean playTone, Integer duration,
+ Integer correlationID) throws SdlException {
Alert msg = RPCRequestFactory.buildAlert(ttsText, alertText1, alertText2,
playTone, duration, correlationID);
@@ -4308,7 +4824,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param playTone -Defines if tone should be played.
* @param duration -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
public void alert(Vector<TTSChunk> ttsChunks,
String alertText1, String alertText2, Boolean playTone,
@@ -4326,10 +4842,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param ttsText -The text to speech message in the form of a string.
* @param playTone -Defines if tone should be played.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(String ttsText, Boolean playTone,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
alert(ttsText, null, null, playTone, null, correlationID);
}
@@ -4340,10 +4857,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param chunks -A list of text/phonemes to speak in the form of ttsChunks.
* @param playTone -Defines if tone should be played.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(Vector<TTSChunk> chunks, Boolean playTone,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
alert(chunks, null, null, playTone, null, correlationID);
}
@@ -4356,10 +4874,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param playTone -Defines if tone should be played.
* @param duration -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void alert(String alertText1, String alertText2,
- Boolean playTone, Integer duration, Integer correlationID)
+ Boolean playTone, Integer duration, Integer correlationID)
throws SdlException {
alert((Vector<TTSChunk>)null, alertText1, alertText2, playTone, duration, correlationID);
@@ -4368,11 +4887,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a CreateInteractionChoiceSet RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param choiceSet
- * @param interactionChoiceSetID
- * @param correlationID
- * @throws SdlException
+ * @param choiceSet to be sent to the module
+ * @param interactionChoiceSetID to be used in reference to the supplied choiceSet
+ * @param correlationID to be set to the RPCRequest
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void createInteractionChoiceSet(
Vector<Choice> choiceSet, Integer interactionChoiceSetID,
Integer correlationID) throws SdlException {
@@ -4388,10 +4908,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param commandID -ID of the command(s) to delete.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void deleteCommand(Integer commandID,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
DeleteCommand msg = RPCRequestFactory.buildDeleteCommand(commandID, correlationID);
@@ -4403,8 +4924,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param interactionChoiceSetID -ID of the interaction choice set to delete.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void deleteInteractionChoiceSet(
Integer interactionChoiceSetID, Integer correlationID)
throws SdlException {
@@ -4420,10 +4942,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param menuID -The menuID of the submenu to delete.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void deleteSubMenu(Integer menuID,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
DeleteSubMenu msg = RPCRequestFactory.buildDeleteSubMenu(menuID, correlationID);
@@ -4442,11 +4965,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
* @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Integer interactionChoiceSetID, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
+ String displayText, Integer interactionChoiceSetID, Vector<VrHelpItem> vrHelp,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt,
displayText, interactionChoiceSetID, vrHelp, correlationID);
@@ -4466,13 +4990,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param timeout -Timeout in milliseconds.
* @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Integer interactionChoiceSetID,
- String helpPrompt, String timeoutPrompt,
- InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
+ String displayText, Integer interactionChoiceSetID,
+ String helpPrompt, String timeoutPrompt,
+ InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(
initPrompt, displayText, interactionChoiceSetID,
@@ -4494,13 +5019,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param timeout -Timeout in milliseconds.
* @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Vector<Integer> interactionChoiceSetIDList,
- String helpPrompt, String timeoutPrompt,
- InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
- Integer correlationID) throws SdlException {
+ String displayText, Vector<Integer> interactionChoiceSetIDList,
+ String helpPrompt, String timeoutPrompt,
+ InteractionMode interactionMode, Integer timeout, Vector<VrHelpItem> vrHelp,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt,
displayText, interactionChoiceSetIDList,
@@ -4522,8 +5048,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param timeout -Timeout in milliseconds.
* @param vrHelp -Suggested VR Help Items to display on-screen during Perform Interaction.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(
Vector<TTSChunk> initChunks, String displayText,
Vector<Integer> interactionChoiceSetIDList,
@@ -4548,11 +5075,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param displayText -Text to be displayed first.
* @param interactionChoiceSetID -Interaction choice set IDs to use with an interaction.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Integer interactionChoiceSetID,
- Integer correlationID) throws SdlException {
+ String displayText, Integer interactionChoiceSetID,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt,
displayText, interactionChoiceSetID, correlationID);
@@ -4571,13 +5099,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
* @param timeout -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Integer interactionChoiceSetID,
- String helpPrompt, String timeoutPrompt,
- InteractionMode interactionMode, Integer timeout,
- Integer correlationID) throws SdlException {
+ String displayText, Integer interactionChoiceSetID,
+ String helpPrompt, String timeoutPrompt,
+ InteractionMode interactionMode, Integer timeout,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(
initPrompt, displayText, interactionChoiceSetID,
@@ -4598,13 +5127,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
* @param timeout -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(String initPrompt,
- String displayText, Vector<Integer> interactionChoiceSetIDList,
- String helpPrompt, String timeoutPrompt,
- InteractionMode interactionMode, Integer timeout,
- Integer correlationID) throws SdlException {
+ String displayText, Vector<Integer> interactionChoiceSetIDList,
+ String helpPrompt, String timeoutPrompt,
+ InteractionMode interactionMode, Integer timeout,
+ Integer correlationID) throws SdlException {
PerformInteraction msg = RPCRequestFactory.buildPerformInteraction(initPrompt,
displayText, interactionChoiceSetIDList,
@@ -4625,8 +5155,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param interactionMode - The method in which the user is notified and uses the interaction (Manual,VR,Both).
* @param timeout -Timeout in milliseconds.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performInteraction(
Vector<TTSChunk> initChunks, String displayText,
Vector<Integer> interactionChoiceSetIDList,
@@ -4648,7 +5179,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
SdlMsgVersion sdlMsgVersion, String appName, Vector<TTSChunk> ttsName,
String ngnMediaScreenAppName, Vector<String> vrSynonyms, Boolean isMediaApp,
Language languageDesired, Language hmiDisplayLanguageDesired, Vector<AppHMIType> appType,
- String appID, String autoActivateID, Integer correlationID)
+ String appID, Integer correlationID)
throws SdlException {
String carrierName = null;
if(telephonyManager != null){
@@ -4680,13 +5211,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param helpPrompt
- * @param timeoutPrompt
- * @param vrHelpTitle
- * @param vrHelp
- * @param correlationID
- * @throws SdlException
+ * @param helpPrompt that will be used for the VR screen
+ * @param timeoutPrompt string to be displayed after timeout
+ * @param vrHelpTitle string that may be displayed on VR prompt dialog
+ * @param vrHelp a list of VR synonyms that may be displayed to user
+ * @param correlationID to be attached to the request
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setGlobalProperties(
String helpPrompt, String timeoutPrompt, String vrHelpTitle, Vector<VrHelpItem> vrHelp, Integer correlationID)
throws SdlException {
@@ -4700,13 +5232,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param helpChunks
- * @param timeoutChunks
- * @param vrHelpTitle
- * @param vrHelp
- * @param correlationID
- * @throws SdlException
+ * @param helpChunks tts chunks that should be used when prompting the user
+ * @param timeoutChunks tts chunks that will be used when a timeout occurs
+ * @param vrHelpTitle string that may be displayed on VR prompt dialog
+ * @param vrHelp a list of VR synonyms that may be displayed to user
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setGlobalProperties(
Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks, String vrHelpTitle, Vector<VrHelpItem> vrHelp,
Integer correlationID) throws SdlException {
@@ -4721,12 +5254,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpPrompt
- * @param timeoutPrompt
- * @param correlationID
- * @throws SdlException
+ *
+ * @param helpPrompt that will be used for the VR screen
+ * @param timeoutPrompt string to be displayed after timeout
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setGlobalProperties(
String helpPrompt, String timeoutPrompt, Integer correlationID)
throws SdlException {
@@ -4739,12 +5273,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a SetGlobalProperties RPCRequest to SDL. Responses are captured through callback on IProxyListener.
- *
- * @param helpChunks
- * @param timeoutChunks
- * @param correlationID
- * @throws SdlException
+ *
+ * @param helpChunks tts chunks that should be used when prompting the user
+ * @param timeoutChunks tts chunks that will be used when a timeout occurs
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setGlobalProperties(
Vector<TTSChunk> helpChunks, Vector<TTSChunk> timeoutChunks,
Integer correlationID) throws SdlException {
@@ -4755,8 +5290,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
sendRPCRequest(req);
}
+ @SuppressWarnings("unused")
public void resetGlobalProperties(Vector<GlobalProperty> properties,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
ResetGlobalProperties req = new ResetGlobalProperties();
@@ -4770,16 +5306,17 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a SetMediaClockTimer RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param hours
- * @param minutes
- * @param seconds
- * @param updateMode
- * @param correlationID
- * @throws SdlException
+ * @param hours integer for hours
+ * @param minutes integer for minutes
+ * @param seconds integer for seconds
+ * @param updateMode mode in which the media clock timer should be updated
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setMediaClockTimer(Integer hours,
- Integer minutes, Integer seconds, UpdateMode updateMode,
- Integer correlationID) throws SdlException {
+ Integer minutes, Integer seconds, UpdateMode updateMode,
+ Integer correlationID) throws SdlException {
SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(hours,
minutes, seconds, updateMode, correlationID);
@@ -4790,10 +5327,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Pauses the media clock. Responses are captured through callback on IProxyListener.
*
- * @param correlationID
- * @throws SdlException
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void pauseMediaClockTimer(Integer correlationID)
+ @SuppressWarnings("unused")
+ public void pauseMediaClockTimer(Integer correlationID)
throws SdlException {
SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(0,
@@ -4805,10 +5343,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Resumes the media clock. Responses are captured through callback on IProxyListener.
*
- * @param correlationID
- * @throws SdlException
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void resumeMediaClockTimer(Integer correlationID)
+ @SuppressWarnings("unused")
+ public void resumeMediaClockTimer(Integer correlationID)
throws SdlException {
SetMediaClockTimer msg = RPCRequestFactory.buildSetMediaClockTimer(0,
@@ -4820,10 +5359,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Clears the media clock. Responses are captured through callback on IProxyListener.
*
- * @param correlationID
- * @throws SdlException
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void clearMediaClockTimer(Integer correlationID)
+ @SuppressWarnings("unused")
+ public void clearMediaClockTimer(Integer correlationID)
throws SdlException {
Show msg = RPCRequestFactory.buildShow(null, null, null, " ", null, null, correlationID);
@@ -4835,24 +5375,25 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param mainText1 -Text displayed in a single or upper display line.
- * @param mainText2 -Text displayed on the second display line.
- * @param mainText3 -Text displayed on the second "page" first display line.
- * @param mainText4 -Text displayed on the second "page" second display line.
- * @param statusBar
- * @param mediaClock -Text value for MediaClock field.
- * @param mediaTrack -Text displayed in the track field.
- * @param graphic -Image struct determining whether static or dynamic image to display in app.
- * @param softButtons -App defined SoftButtons.
- * @param customPresets -App labeled on-screen presets.
- * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @param mainText1 text displayed in a single or upper display line.
+ * @param mainText2 text displayed on the second display line.
+ * @param mainText3 text displayed on the second "page" first display line.
+ * @param mainText4 text displayed on the second "page" second display line.
+ * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps)
+ * @param mediaClock text value for MediaClock field.
+ * @param mediaTrack text displayed in the track field.
+ * @param graphic image struct determining whether static or dynamic image to display in app.
+ * @param softButtons app defined SoftButtons.
+ * @param customPresets app labeled on-screen presets.
+ * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display.
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse -A unique ID that correlates each RPCRequest and RPCResponse.
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void show(String mainText1, String mainText2, String mainText3, String mainText4,
- String statusBar, String mediaClock, String mediaTrack,
- Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
- TextAlignment alignment, Integer correlationID)
+ String statusBar, String mediaClock, String mediaTrack,
+ Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
+ TextAlignment alignment, Integer correlationID)
throws SdlException {
Show msg = RPCRequestFactory.buildShow(mainText1, mainText2, mainText3, mainText4,
@@ -4874,11 +5415,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param customPresets -App labeled on-screen presets.
* @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void show(String mainText1, String mainText2, String mainText3, String mainText4,
- Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
- TextAlignment alignment, Integer correlationID)
+ Image graphic, Vector<SoftButton> softButtons, Vector <String> customPresets,
+ TextAlignment alignment, Integer correlationID)
throws SdlException {
show(mainText1, mainText2, mainText3, mainText4, null, null, null, graphic, softButtons, customPresets, alignment, correlationID);
@@ -4888,18 +5430,19 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Sends a Show RPCRequest to SDL. Responses are captured through callback on IProxyListener.
*
- * @param mainText1 -Text displayed in a single or upper display line.
- * @param mainText2 -Text displayed on the second display line.
- * @param statusBar
- * @param mediaClock -Text value for MediaClock field.
- * @param mediaTrack -Text displayed in the track field.
- * @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
- * @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @param mainText1 text displayed in a single or upper display line.
+ * @param mainText2 text displayed on the second display line.
+ * @param statusBar text is placed in the status bar area (Only valid for NAVIGATION apps)
+ * @param mediaClock text value for MediaClock field.
+ * @param mediaTrack text displayed in the track field.
+ * @param alignment specifies how mainText1 and mainText2s texts should be aligned on display.
+ * @param correlationID unique ID that correlates each RPCRequest and RPCResponse.
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("SameParameterValue")
public void show(String mainText1, String mainText2,
- String statusBar, String mediaClock, String mediaTrack,
- TextAlignment alignment, Integer correlationID)
+ String statusBar, String mediaClock, String mediaTrack,
+ TextAlignment alignment, Integer correlationID)
throws SdlException {
Show msg = RPCRequestFactory.buildShow(mainText1, mainText2,
@@ -4916,10 +5459,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param mainText2 -Text displayed on the second display line.
* @param alignment -Specifies how mainText1 and mainText2s texts should be aligned on display.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void show(String mainText1, String mainText2,
- TextAlignment alignment, Integer correlationID)
+ TextAlignment alignment, Integer correlationID)
throws SdlException {
show(mainText1, mainText2, null, null, null, alignment, correlationID);
@@ -4930,9 +5474,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param ttsText -The text to speech message in the form of a string.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void speak(String ttsText, Integer correlationID)
+ @SuppressWarnings("unused")
+ public void speak(String ttsText, Integer correlationID)
throws SdlException {
Speak msg = RPCRequestFactory.buildSpeak(TTSChunkFactory.createSimpleTTSChunks(ttsText),
@@ -4946,10 +5491,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param ttsChunks -Text/phonemes to speak in the form of ttsChunks.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void speak(Vector<TTSChunk> ttsChunks,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
Speak msg = RPCRequestFactory.buildSpeak(ttsChunks, correlationID);
@@ -4961,10 +5507,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param buttonName -Name of the button to subscribe.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void subscribeButton(ButtonName buttonName,
- Integer correlationID) throws SdlException {
+ Integer correlationID) throws SdlException {
SubscribeButton msg = RPCRequestFactory.buildSubscribeButton(buttonName,
correlationID);
@@ -4995,10 +5542,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param buttonName -Name of the button to unsubscribe.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void unsubscribeButton(ButtonName buttonName,
- Integer correlationID) throws SdlException {
+ @SuppressWarnings("unused")
+ public void unsubscribeButton(ButtonName buttonName,
+ Integer correlationID) throws SdlException {
UnsubscribeButton msg = RPCRequestFactory.buildUnsubscribeButton(
buttonName, correlationID);
@@ -5014,10 +5562,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param choiceVrCommands -Vector of vrCommands used to select this choice by voice. Must contain
* at least one non-empty element.
* @return Choice created.
- * @throws SdlException
*/
+ @SuppressWarnings("unused")
public Choice createChoiceSetChoice(Integer choiceID, String choiceMenuName,
- Vector<String> choiceVrCommands) {
+ Vector<String> choiceVrCommands) {
Choice returnChoice = new Choice();
returnChoice.setChoiceID(choiceID);
@@ -5039,11 +5587,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param audioType -Specifies the type of audio data being requested.
* @param muteAudio -Defines if the current audio source should be muted during the APT session.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void performaudiopassthru(String initialPrompt, String audioPassThruDisplayText1, String audioPassThruDisplayText2,
- SamplingRate samplingRate, Integer maxDuration, BitsPerSample bitsPerSample,
- AudioType audioType, Boolean muteAudio, Integer correlationID) throws SdlException {
+ SamplingRate samplingRate, Integer maxDuration, BitsPerSample bitsPerSample,
+ AudioType audioType, Boolean muteAudio, Integer correlationID) throws SdlException {
PerformAudioPassThru msg = RPCRequestFactory.BuildPerformAudioPassThru(initialPrompt, audioPassThruDisplayText1, audioPassThruDisplayText2,
samplingRate, maxDuration, bitsPerSample, audioType, muteAudio, correlationID);
@@ -5053,10 +5602,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Ends audio pass thru session. Responses are captured through callback on IProxyListener.
*
- * @param correlationID
- * @throws SdlException
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void endaudiopassthru(Integer correlationID) throws SdlException
+ @SuppressWarnings("unused")
+ public void endaudiopassthru(Integer correlationID) throws SdlException
{
EndAudioPassThru msg = RPCRequestFactory.BuildEndAudioPassThru(correlationID);
sendRPCRequest(msg);
@@ -5081,10 +5631,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param deviceStatus -Subscribes to device status including signal and battery strength.
* @param driverBraking -Subscribes to the status of the brake pedal.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void subscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
+ boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
boolean driverBraking, Integer correlationID) throws SdlException
{
@@ -5113,13 +5664,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param deviceStatus -Unsubscribes to device status including signal and battery strength.
* @param driverBraking -Unsubscribes to the status of the brake pedal.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void unsubscribevehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
- boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
+ boolean instantFuelConsumption, boolean externalTemperature, boolean prndl, boolean tirePressure,
+ boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
+ boolean driverBraking, Integer correlationID) throws SdlException
{
UnsubscribeVehicleData msg = RPCRequestFactory.BuildUnsubscribeVehicleData(gps, speed, rpm, fuelLevel, fuelLevel_State, instantFuelConsumption, externalTemperature, prndl, tirePressure,
odometer, beltStatus, bodyInformation, deviceStatus, driverBraking, correlationID);
@@ -5147,12 +5699,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param deviceStatus -Performs an ad-hoc request for device status including signal and battery strength.
* @param driverBraking -Performs an ad-hoc request for the status of the brake pedal.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void getvehicledata(boolean gps, boolean speed, boolean rpm, boolean fuelLevel, boolean fuelLevel_State,
- boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure,
- boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
- boolean driverBraking, Integer correlationID) throws SdlException
+ boolean instantFuelConsumption, boolean externalTemperature, boolean vin, boolean prndl, boolean tirePressure,
+ boolean odometer, boolean beltStatus, boolean bodyInformation, boolean deviceStatus,
+ boolean driverBraking, Integer correlationID) throws SdlException
{
GetVehicleData msg = RPCRequestFactory.BuildGetVehicleData(gps, speed, rpm, fuelLevel, fuelLevel_State, instantFuelConsumption, externalTemperature, vin, prndl, tirePressure, odometer,
@@ -5169,8 +5722,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param timeout -App defined timeout. Indicates how long of a timeout from the last action.
* @param softButtons -App defined SoftButtons.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void scrollablemessage(String scrollableMessageBody, Integer timeout, Vector<SoftButton> softButtons, Integer correlationID) throws SdlException
{
ScrollableMessage msg = RPCRequestFactory.BuildScrollableMessage(scrollableMessageBody, timeout, softButtons, correlationID);
@@ -5188,8 +5742,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param sliderFooter - Text footer to display (meant to display min/max threshold descriptors).
* @param timeout -App defined timeout. Indicates how long of a timeout from the last action.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void slider(Integer numTicks, Integer position, String sliderHeader, Vector<String> sliderFooter, Integer timeout, Integer correlationID) throws SdlException
{
Slider msg = RPCRequestFactory.BuildSlider(numTicks, position, sliderHeader, sliderFooter, timeout, correlationID);
@@ -5199,11 +5754,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
/**
* Responses are captured through callback on IProxyListener.
*
- * @param language
- * @param hmiDisplayLanguage
- * @param correlationID
- * @throws SdlException
+ * @param language requested SDL voice engine (VR+TTS) language registration
+ * @param hmiDisplayLanguage request display language registration.
+ * @param correlationID ID to be attached to the RPCRequest that correlates the RPCResponse
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void changeregistration(Language language, Language hmiDisplayLanguage, Integer correlationID) throws SdlException
{
ChangeRegistration msg = RPCRequestFactory.BuildChangeRegistration(language, hmiDisplayLanguage, correlationID);
@@ -5219,13 +5775,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param iOffset - The data offset in bytes, a value of zero is used to indicate data starting from the beginging of the file.
* A value greater than zero is used for resuming partial data chunks.
* @param iLength - The total length of the file being sent.
- * @throws SdlException
- * @see {@link#putFileStream(InputStream, String, Long, Long)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(InputStream, String, Long, Long)
*/
+ @SuppressWarnings("unused")
@Deprecated
public void putFileStream(InputStream is, String sdlFileName, Integer iOffset, Integer iLength) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength);
startRPCStream(is, msg);
}
@@ -5239,8 +5796,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* indicate data starting from the beginning of the file and a value greater
* than zero is used for resuming partial data chunks.
* @param length The total length of the file being sent.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void putFileStream(InputStream inputStream, String fileName, Long offset, Long length) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, length);
startRPCStream(inputStream, msg);
@@ -5256,13 +5814,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param iLength - The total length of the file being sent.
*
* @return OutputStream - The output stream of byte data that is written to by the app developer
- * @throws SdlException
- * @see {@link#putFileStream(String, Long, Long)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(String, Long, Long)
*/
+ @SuppressWarnings("unused")
@Deprecated
public OutputStream putFileStream(String sdlFileName, Integer iOffset, Integer iLength) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength);
return startRPCStream(msg);
}
@@ -5275,8 +5834,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* indicate data starting from the beginning of the file and a value greater
* than zero is used for resuming partial data chunks.
* @param length The total length of the file being sent.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public OutputStream putFileStream(String fileName, Long offset, Long length) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, length);
return startRPCStream(msg);
@@ -5294,13 +5854,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param fileType - The selected file type -- see the FileType enumeration for details
* @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
* @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @throws SdlException
- * @see {@link#putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener)
*/
+ @SuppressWarnings("unused")
@Deprecated
public void putFileStream(InputStream is, String sdlFileName, Integer iOffset, Integer iLength, FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile);
startRPCStream(is, msg);
}
@@ -5320,8 +5881,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* sessions / ignition cycles.
* @param isSystemFile Indicates if the file is meant to be passed through
* core to elsewhere in the system.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void putFileStream(InputStream inputStream, String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, length);
msg.setOnPutFileUpdateListener(cb);
@@ -5340,13 +5902,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
* @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
* @return OutputStream - The output stream of byte data that is written to by the app developer
- * @throws SdlException
- * @see {@link#putFileStream(String, Long, Long, FileType, Boolean, Boolean)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(String, Long, Long, FileType, Boolean, Boolean, OnPutFileUpdateListener)
*/
+ @SuppressWarnings("unused")
@Deprecated
public OutputStream putFileStream(String sdlFileName, Integer iOffset, Integer iLength, FileType fileType, Boolean bPersistentFile, Boolean bSystemFile) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile);
return startRPCStream(msg);
}
@@ -5365,8 +5928,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* sessions / ignition cycles.
* @param isSystemFile Indicates if the file is meant to be passed through
* core to elsewhere in the system.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public OutputStream putFileStream(String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, OnPutFileUpdateListener cb) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, length);
msg.setOnPutFileUpdateListener(cb);
@@ -5384,15 +5948,16 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param fileType - The selected file type -- see the FileType enumeration for details
* @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
* @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @param correlationID - A unique ID that correlates each RPCRequest and RPCResponse.
+ * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse.
* @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned
- * @throws SdlException
- * @see {@link#putFileStream(String, String, Long, FileType, Boolean, Boolean, Integer)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(String, String, Long, FileType, Boolean, Boolean, Boolean, Integer, OnPutFileUpdateListener)
*/
+ @SuppressWarnings("unused")
@Deprecated
public RPCStreamController putFileStream(String sPath, String sdlFileName, Integer iOffset, FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, 0, fileType, bPersistentFile, bSystemFile, iCorrelationID);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, 0, fileType, bPersistentFile, bSystemFile, iCorrelationID);
return startPutFileStream(sPath, msg);
}
@@ -5416,8 +5981,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @return RPCStreamController If the putFileStream was not started
* successfully null is returned, otherwise a valid object reference is
* returned .
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public RPCStreamController putFileStream(String path, String fileName, Long offset, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId, OnPutFileUpdateListener cb ) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, 0L, fileType, isPersistentFile, isSystemFile, isPayloadProtected, correlationId);
msg.setOnPutFileUpdateListener(cb);
@@ -5435,15 +6001,16 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param fileType - The selected file type -- see the FileType enumeration for details
* @param bPersistentFile - Indicates if the file is meant to persist between sessions / ignition cycles.
* @param bSystemFile - Indicates if the file is meant to be passed thru core to elsewhere on the system.
- * @param correlationID - A unique ID that correlates each RPCRequest and RPCResponse.
+ * @param iCorrelationID - A unique ID that correlates each RPCRequest and RPCResponse.
* @return RPCStreamController - If the putFileStream was not started successfully null is returned, otherwise a valid object reference is returned
- * @throws SdlException
- * @see {@link#putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, Integer)}
+ * @throws SdlException if an unrecoverable error is encountered
+ * @see #putFileStream(InputStream, String, Long, Long, FileType, Boolean, Boolean, Boolean, Integer)
*/
+ @SuppressWarnings("unused")
@Deprecated
public RPCStreamController putFileStream(InputStream is, String sdlFileName, Integer iOffset, Integer iLength, FileType fileType, Boolean bPersistentFile, Boolean bSystemFile, Integer iCorrelationID) throws SdlException
{
- PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile, iCorrelationID);
+ @SuppressWarnings("deprecation") PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, iOffset, iLength, fileType, bPersistentFile, bSystemFile, iCorrelationID);
return startPutFileStream(is, msg);
}
@@ -5465,8 +6032,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* core to elsewhere in the system.
* @param correlationId A unique id that correlates each RPCRequest and
* RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public RPCStreamController putFileStream(InputStream inputStream, String fileName, Long offset, Long length, FileType fileType, Boolean isPersistentFile, Boolean isSystemFile, Boolean isPayloadProtected, Integer correlationId) throws SdlException {
PutFile msg = RPCRequestFactory.buildPutFile(fileName, offset, length, fileType, isPersistentFile, isSystemFile, isPayloadProtected, correlationId);
return startPutFileStream(inputStream, msg);
@@ -5477,6 +6045,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* Used to end an existing putFileStream that was previously initiated with any putFileStream method.
*
*/
+ @SuppressWarnings("unused")
public void endPutFileStream()
{
endRPCStream();
@@ -5490,11 +6059,12 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* @param sdlFileName -File reference name.
* @param fileType -Selected file type.
* @param persistentFile -Indicates if the file is meant to persist between sessions / ignition cycles.
- * @param fileData
+ * @param fileData byte array of data of the file that is to be sent
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void putfile(String sdlFileName, FileType fileType, Boolean persistentFile, byte[] fileData, Integer correlationID) throws SdlException
+ @SuppressWarnings("unused")
+ public void putfile(String sdlFileName, FileType fileType, Boolean persistentFile, byte[] fileData, Integer correlationID) throws SdlException
{
PutFile msg = RPCRequestFactory.buildPutFile(sdlFileName, fileType, persistentFile, fileData, correlationID);
sendRPCRequest(msg);
@@ -5506,9 +6076,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param sdlFileName -File reference name.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void deletefile(String sdlFileName, Integer correlationID) throws SdlException
+ @SuppressWarnings("unused")
+ public void deletefile(String sdlFileName, Integer correlationID) throws SdlException
{
DeleteFile msg = RPCRequestFactory.buildDeleteFile(sdlFileName, correlationID);
sendRPCRequest(msg);
@@ -5519,8 +6090,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
* Responses are captured through callback on IProxyListener.
*
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void listfiles(Integer correlationID) throws SdlException
{
ListFiles msg = RPCRequestFactory.buildListFiles(correlationID);
@@ -5533,9 +6105,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param sdlFileName -File reference name.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
- public void setappicon(String sdlFileName, Integer correlationID) throws SdlException
+ @SuppressWarnings("unused")
+ public void setappicon(String sdlFileName, Integer correlationID) throws SdlException
{
SetAppIcon msg = RPCRequestFactory.buildSetAppIcon(sdlFileName, correlationID);
sendRPCRequest(msg);
@@ -5547,23 +6120,26 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @param displayLayout -Predefined or dynamically created screen layout.
* @param correlationID -A unique ID that correlates each RPCRequest and RPCResponse.
- * @throws SdlException
+ * @throws SdlException if an unrecoverable error is encountered
*/
+ @SuppressWarnings("unused")
public void setdisplaylayout(String displayLayout, Integer correlationID) throws SdlException
{
SetDisplayLayout msg = RPCRequestFactory.BuildSetDisplayLayout(displayLayout, correlationID);
sendRPCRequest(msg);
}
+ @SuppressWarnings("unused")
public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener){
_systemCapabilityManager.getCapability(systemCapabilityType, scListener);
}
+ @SuppressWarnings("unused")
public Object getCapability(SystemCapabilityType systemCapabilityType){
return _systemCapabilityManager.getCapability(systemCapabilityType);
}
- /******************** END Public Helper Methods *************************/
+ /* ******************* END Public Helper Methods *************************/
/**
* Gets type of transport currently used by this SdlProxy.
@@ -5572,6 +6148,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
*
* @see TransportType
*/
+ @SuppressWarnings("unused")
public TransportType getCurrentTransportType() throws IllegalStateException {
if (sdlSession == null) {
throw new IllegalStateException("Incorrect state of SdlProxyBase: Calling for getCurrentTransportType() while connection is not initialized");
@@ -5591,12 +6168,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
}
}
- public boolean isServiceTypeProtected(SessionType sType)
- {
- if (sdlSession == null)
- return false;
-
- return sdlSession.isServiceProtected(sType);
+ @SuppressWarnings("unused")
+ public boolean isServiceTypeProtected(SessionType sType) {
+ return sdlSession != null && sdlSession.isServiceProtected(sType);
+
}
@@ -5621,37 +6196,45 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase>
return _proxyListener;
}
+ @SuppressWarnings("unused")
public String getAppName()
{
return _applicationName;
}
+ @SuppressWarnings("unused")
public String getNgnAppName()
{
return _ngnMediaScreenAppName;
}
+ @SuppressWarnings("unused")
public String getAppID()
{
return _appID;
}
+ @SuppressWarnings("unused")
public DeviceInfo getDeviceInfo()
{
return deviceInfo;
}
+ @SuppressWarnings("unused")
public long getInstanceDT()
{
return instanceDateTime;
}
+ @SuppressWarnings("unused")
public void setConnectionDetails(String sDetails)
{
sConnectionDetails = sDetails;
}
+ @SuppressWarnings("unused")
public String getConnectionDetails()
{
return sConnectionDetails;
}
//for testing only
+ @SuppressWarnings("unused")
public void setPoliciesURL(String sText)
{
sPoliciesURL = sText;
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java
index bd0edb48b..b5dac4768 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/SystemCapabilityManager.java
@@ -1,5 +1,7 @@
package com.smartdevicelink.proxy;
+import com.smartdevicelink.exception.SdlException;
+import com.smartdevicelink.proxy.interfaces.ISdl;
import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener;
import com.smartdevicelink.proxy.rpc.GetSystemCapability;
import com.smartdevicelink.proxy.rpc.GetSystemCapabilityResponse;
@@ -17,13 +19,9 @@ import java.util.List;
public class SystemCapabilityManager {
HashMap<SystemCapabilityType, Object> cachedSystemCapabilities = new HashMap<>();
- ISystemCapabilityManager callback;
+ ISdl callback;
- public interface ISystemCapabilityManager{
- void onSendPacketRequest(RPCRequest message);
- }
-
- public SystemCapabilityManager(ISystemCapabilityManager callback){
+ public SystemCapabilityManager(ISdl callback){
this.callback = callback;
}
@@ -69,6 +67,8 @@ public class SystemCapabilityManager {
return hmiCapabilities.isPhoneCallAvailable();
case VIDEO_STREAMING:
return hmiCapabilities.isVideoStreamingAvailable();
+ case REMOTE_CONTROL:
+ return hmiCapabilities.isRemoteControlAvailable();
default:
return false;
}
@@ -133,7 +133,7 @@ public class SystemCapabilityManager {
request.setCorrelationID(CorrelationIdGenerator.generateId());
if(callback!=null){
- callback.onSendPacketRequest(request);
+ callback.sendRPCRequest(request);
}
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IAudioStreamListener.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IAudioStreamListener.java
new file mode 100644
index 000000000..8d21b7615
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IAudioStreamListener.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.proxy.interfaces;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A listener that receives audio streaming data from app.
+ */
+public interface IAudioStreamListener {
+ /**
+ * Sends a chunk of audio data to SDL Core.
+ * <p>
+ * Note: this method must not be called after SdlProxyBase.endAudioStream() is called.
+ *
+ * @param data Byte array containing audio data
+ * @param offset Starting offset in 'data'
+ * @param length Length of the data
+ * @param presentationTimeUs (Reserved for future use) Presentation timestamp (PTS) of the
+ * last audio sample data included in this chunk, in microseconds.
+ * It must be greater than the previous timestamp.
+ * Specify -1 if unknown.
+ * @throws ArrayIndexOutOfBoundsException When offset does not satisfy
+ * {@code 0 <= offset && offset <= data.length}
+ * or length does not satisfy
+ * {@code 0 < length && offset + length <= data.length}
+ */
+ void sendAudio(byte[] data, int offset, int length, long presentationTimeUs)
+ throws ArrayIndexOutOfBoundsException;
+
+ /**
+ * Sends a chunk of audio data to SDL Core.
+ * <p>
+ * Note: this method must not be called after SdlProxyBase.endAudioStream() is called.
+ *
+ * @param data Data chunk to send. Its position will be updated upon return.
+ * @param presentationTimeUs (Reserved for future use) Presentation timestamp (PTS) of the
+ * last audio sample data included in this chunk, in microseconds.
+ * It must be greater than the previous timestamp.
+ * Specify -1 if unknown.
+ */
+ void sendAudio(ByteBuffer data, long presentationTimeUs);
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
index 80842cfc2..618819f20 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IProxyListenerBase.java
@@ -6,6 +6,7 @@ import com.smartdevicelink.proxy.rpc.AddCommandResponse;
import com.smartdevicelink.proxy.rpc.AddSubMenuResponse;
import com.smartdevicelink.proxy.rpc.AlertManeuverResponse;
import com.smartdevicelink.proxy.rpc.AlertResponse;
+import com.smartdevicelink.proxy.rpc.ButtonPressResponse;
import com.smartdevicelink.proxy.rpc.ChangeRegistrationResponse;
import com.smartdevicelink.proxy.rpc.CreateInteractionChoiceSetResponse;
import com.smartdevicelink.proxy.rpc.DeleteCommandResponse;
@@ -17,6 +18,7 @@ import com.smartdevicelink.proxy.rpc.DialNumberResponse;
import com.smartdevicelink.proxy.rpc.EndAudioPassThruResponse;
import com.smartdevicelink.proxy.rpc.GenericResponse;
import com.smartdevicelink.proxy.rpc.GetDTCsResponse;
+import com.smartdevicelink.proxy.rpc.GetInteriorVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.GetSystemCapabilityResponse;
import com.smartdevicelink.proxy.rpc.GetVehicleDataResponse;
import com.smartdevicelink.proxy.rpc.GetWayPointsResponse;
@@ -28,6 +30,7 @@ import com.smartdevicelink.proxy.rpc.OnCommand;
import com.smartdevicelink.proxy.rpc.OnDriverDistraction;
import com.smartdevicelink.proxy.rpc.OnHMIStatus;
import com.smartdevicelink.proxy.rpc.OnHashChange;
+import com.smartdevicelink.proxy.rpc.OnInteriorVehicleData;
import com.smartdevicelink.proxy.rpc.OnKeyboardInput;
import com.smartdevicelink.proxy.rpc.OnLanguageChange;
import com.smartdevicelink.proxy.rpc.OnLockScreenStatus;
@@ -49,6 +52,7 @@ import com.smartdevicelink.proxy.rpc.SendLocationResponse;
import com.smartdevicelink.proxy.rpc.SetAppIconResponse;
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.ShowConstantTbtResponse;
import com.smartdevicelink.proxy.rpc.ShowResponse;
@@ -340,5 +344,13 @@ public interface IProxyListenerBase {
public void onGetSystemCapabilityResponse(GetSystemCapabilityResponse response);
+ public void onGetInteriorVehicleDataResponse(GetInteriorVehicleDataResponse response);
+
+ public void onButtonPressResponse(ButtonPressResponse response);
+
+ public void onSetInteriorVehicleDataResponse(SetInteriorVehicleDataResponse response);
+
+ public void onOnInteriorVehicleData(OnInteriorVehicleData notification);
+
public void onSendHapticDataResponse(SendHapticDataResponse response);
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/ISdl.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/ISdl.java
new file mode 100644
index 000000000..2d67f93d7
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/ISdl.java
@@ -0,0 +1,116 @@
+package com.smartdevicelink.proxy.interfaces;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
+import com.smartdevicelink.streaming.VideoStreamingParameters;
+
+/*
+ * Copyright (c) 2017 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.
+ */
+@SuppressWarnings("unused")
+public interface ISdl {
+
+ /**
+ * Starts the connection with the module
+ */
+ void start();
+
+ /**
+ * Ends connection with the module
+ */
+ void stop();
+
+ /**
+ * Method to check if the session is connected
+ * @return if there is a connected session
+ */
+ boolean isConnected();
+
+ /**
+ * Add a service listener for a specific service type
+ * @param serviceType service type that the listener will be attached to
+ * @param sdlServiceListener listener for events that happen to the service
+ */
+ void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener);
+
+ /**
+ * Remote a service listener for a specific service type
+ * @param serviceType service type that the listener was attached to
+ * @param sdlServiceListener service listener that was previously added for the service type
+ */
+ void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener);
+
+ /**
+ * Starts the video streaming service
+ * @param parameters desired video streaming params for this sevice to be started with
+ * @param encrypted flag to start this service with encryption or not
+ */
+ void startVideoService(VideoStreamingParameters parameters, boolean encrypted);
+
+ /**
+ * Stops the video service if open
+ */
+ void stopVideoService();
+
+ /**
+ * Starts the Audio streaming service
+ * @param encrypted flag to start this service with encryption or not
+ */
+ void startAudioService(boolean encrypted);
+
+ /**
+ * Stops the audio service if open
+ */
+ void stopAudioService();
+
+ /**
+ * Pass an RPC message through the proxy to be sent to the connected module
+ * @param message RPCRequest that should be sent to the module
+ */
+ void sendRPCRequest(RPCRequest message);
+
+ /**
+ * Add an OnRPCNotificationListener for specified notification
+ * @param notificationId FunctionID of the notification that is to be listened for
+ * @param listener listener that should be added for the notification ID
+ */
+ void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener);
+
+ /**
+ * Removes an OnRPCNotificationListener for specified notification
+ * @param notificationId FunctionID of the notification that was to be listened for
+ * @param listener listener that was previously added for the notification ID
+ */
+ boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener);
+
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IVideoStreamListener.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IVideoStreamListener.java
new file mode 100644
index 000000000..f645b0d55
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/interfaces/IVideoStreamListener.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.proxy.interfaces;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A listener that receives video streaming data from app.
+ */
+public interface IVideoStreamListener {
+
+ /**
+ * Sends a chunk of data which represents a frame to SDL Core.
+ * <p>
+ * The format of the chunk should align with MediaCodec's "Compressed Buffer" format, i.e. it
+ * should contain a single video frame, and it should start and end on frame boundaries.
+ * Please refer to https://developer.android.com/reference/android/media/MediaCodec.html
+ * Also, for H.264 codec case the stream must be in byte-stream format (also known as Annex-B
+ * format). This isn't explained in the document above, but MediaCodec does output in this
+ * format.
+ * <p>
+ * In short, you can just provide MediaCodec's data outputs to this method without tweaking
+ * any data.
+ * <p>
+ * Note: this method must not be called after SdlProxyBase.endVideoStream() is called.
+ *
+ * @param data Byte array containing a video frame
+ * @param offset Starting offset in 'data'
+ * @param length Length of the data
+ * @param presentationTimeUs Presentation timestamp (PTS) of this frame, in microseconds.
+ * It must be greater than the previous timestamp.
+ * Specify -1 if unknown.
+ * @throws ArrayIndexOutOfBoundsException When offset does not satisfy
+ * {@code 0 <= offset && offset <= data.length}
+ * or length does not satisfy
+ * {@code 0 < length && offset + length <= data.length}
+ */
+ void sendFrame(byte[] data, int offset, int length, long presentationTimeUs)
+ throws ArrayIndexOutOfBoundsException;
+
+ /**
+ * Sends chunks of data which represent a frame to SDL Core.
+ * <p>
+ * The format of the chunk should align with MediaCodec's "Compressed Buffer" format, i.e. it
+ * should contain a single video frame, and it should start and end on frame boundaries.
+ * Please refer to https://developer.android.com/reference/android/media/MediaCodec.html
+ * Also, for H.264 codec case the stream must be in byte-stream format (also known as Annex-B
+ * format). This isn't explained in the document above, but MediaCodec does output in this
+ * format.
+ * <p>
+ * In short, you can just provide MediaCodec's data outputs to this method without tweaking
+ * any data.
+ * <p>
+ * Note: this method must not be called after SdlProxyBase.endVideoStream() is called.
+ *
+ * @param data Data chunk to send. Its position will be updated upon return.
+ * @param presentationTimeUs Presentation timestamp (PTS) of this frame, in microseconds.
+ * It must be greater than the previous timestamp.
+ * Specify -1 if unknown.
+ */
+ void sendFrame(ByteBuffer data, long presentationTimeUs);
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPress.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPress.java
new file mode 100644
index 000000000..d0162e7ac
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPress.java
@@ -0,0 +1,94 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.rpc.enums.ButtonName;
+import com.smartdevicelink.proxy.rpc.enums.ButtonPressMode;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+import java.util.Hashtable;
+
+/**
+ * This function allows a remote control type mobile application
+ * simulate a hardware button press event.
+ */
+public class ButtonPress extends RPCRequest {
+ public static final String KEY_MODULE_TYPE = "moduleType";
+ public static final String KEY_BUTTON_NAME = "buttonName";
+ public static final String KEY_BUTTON_PRESS_MODE = "buttonPressMode";
+
+ /**
+ * Constructs a new ButtonPress object
+ */
+ public ButtonPress() {
+ super(FunctionID.BUTTON_PRESS.toString());
+ }
+
+ /**
+ * <p>Constructs a new ButtonPress object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public ButtonPress(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Gets the ModuleType
+ *
+ * @return ModuleType - The module where the button should be pressed
+ */
+ public ModuleType getModuleType() {
+ return (ModuleType) getObject(ModuleType.class, KEY_MODULE_TYPE);
+ }
+
+ /**
+ * Sets a ModuleType
+ *
+ * @param moduleType
+ * Represents module where the button should be pressed
+ */
+ public void setModuleType(ModuleType moduleType) {
+ setParameters(KEY_MODULE_TYPE, moduleType);
+ }
+
+ /**
+ * Gets the ButtonName
+ *
+ * @return ButtonName - The name of supported RC climate or radio button
+ */
+ public ButtonName getButtonName() {
+ return (ButtonName) getObject(ButtonName.class, KEY_BUTTON_NAME);
+ }
+
+ /**
+ * Sets a ButtonName
+ *
+ * @param buttonName
+ * Represents name of supported RC climate or radio button
+ */
+ public void setButtonName(ButtonName buttonName) {
+ setParameters(KEY_BUTTON_NAME, buttonName);
+ }
+
+ /**
+ * Gets the ButtonPressMode
+ *
+ * @return ButtonPressMode - Indicates whether this is a LONG or SHORT button press event.
+ */
+ public ButtonPressMode getButtonPressMode() {
+ return (ButtonPressMode) getObject(ButtonPressMode.class, KEY_BUTTON_PRESS_MODE);
+ }
+
+ /**
+ * Sets a ButtonPressMode
+ *
+ * @param buttonPressMode
+ * Indicates whether this is a LONG or SHORT button press event.
+ */
+ public void setButtonPressMode(ButtonPressMode buttonPressMode) {
+ setParameters(KEY_BUTTON_PRESS_MODE, buttonPressMode);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPressResponse.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPressResponse.java
new file mode 100644
index 000000000..94ccd61a6
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ButtonPressResponse.java
@@ -0,0 +1,28 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCResponse;
+
+import java.util.Hashtable;
+
+public class ButtonPressResponse extends RPCResponse {
+
+ /**
+ * Constructs a new ButtonPressResponse object
+ */
+ public ButtonPressResponse() {
+ super(FunctionID.BUTTON_PRESS.toString());
+ }
+
+ /**
+ * <p>Constructs a new ButtonPressResponse object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public ButtonPressResponse(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlCapabilities.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlCapabilities.java
new file mode 100644
index 000000000..ac9c3fc1c
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlCapabilities.java
@@ -0,0 +1,280 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Contains information about a climate control module's capabilities.
+ */
+
+public class ClimateControlCapabilities extends RPCStruct{
+ public static final String KEY_MODULE_NAME= "moduleName";
+ public static final String KEY_FAN_SPEED_AVAILABLE= "fanSpeedAvailable";
+ public static final String KEY_DESIRED_TEMPERATURE_AVAILABLE= "desiredTemperatureAvailable";
+ public static final String KEY_AC_ENABLE_AVAILABLE= "acEnableAvailable";
+ public static final String KEY_AC_MAX_ENABLE_AVAILABLE= "acMaxEnableAvailable";
+ public static final String KEY_CIRCULATE_AIR_ENABLE_AVAILABLE= "circulateAirEnableAvailable";
+ public static final String KEY_AUTO_MODE_ENABLE_AVAILABLE= "autoModeEnableAvailable";
+ public static final String KEY_DUAL_MODE_ENABLE_AVAILABLE= "dualModeEnableAvailable";
+ public static final String KEY_DEFROST_ZONE_AVAILABLE= "defrostZoneAvailable";
+ public static final String KEY_DEFROST_ZONE= "defrostZone";
+ public static final String KEY_VENTILATION_MODE_AVAILABLE= "ventilationModeAvailable";
+ public static final String KEY_VENTILATION_MODE= "ventilationMode";
+
+ public ClimateControlCapabilities() {
+ }
+
+ public ClimateControlCapabilities(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the moduleName portion of the ClimateControlCapabilities class
+ *
+ * @param moduleName
+ * The short friendly name of the climate control module.
+ * It should not be used to identify a module by mobile application.
+ */
+ public void setModuleName(String moduleName) {
+ setValue(KEY_MODULE_NAME, moduleName);
+ }
+
+ /**
+ * Gets the moduleName portion of the ClimateControlCapabilities class
+ *
+ * @return String - Short friendly name of the climate control module.
+ */
+ public String getModuleName() {
+ return getString(KEY_MODULE_NAME);
+ }
+
+ /**
+ * Sets the fanSpeedAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param fanSpeedAvailable
+ * Availability of the control of fan speed.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setFanSpeedAvailable(Boolean fanSpeedAvailable) {
+ setValue(KEY_FAN_SPEED_AVAILABLE, fanSpeedAvailable);
+ }
+
+ /**
+ * Gets the fanSpeedAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of fan speed.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getFanSpeedAvailable() {
+ return getBoolean(KEY_FAN_SPEED_AVAILABLE);
+ }
+
+ /**
+ * Sets the desiredTemperatureAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param desiredTemperatureAvailable
+ * Availability of the control of desired temperature.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setDesiredTemperatureAvailable(Boolean desiredTemperatureAvailable) {
+ setValue(KEY_DESIRED_TEMPERATURE_AVAILABLE, desiredTemperatureAvailable);
+ }
+
+ /**
+ * Gets the desiredTemperatureAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of desired temperature.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getDesiredTemperatureAvailable() {
+ return getBoolean(KEY_DESIRED_TEMPERATURE_AVAILABLE);
+ }
+
+ /**
+ * Sets the acEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param acEnableAvailable
+ * Availability of the control of turn on/off AC.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setAcEnableAvailable(Boolean acEnableAvailable) {
+ setValue(KEY_AC_ENABLE_AVAILABLE, acEnableAvailable);
+ }
+
+ /**
+ * Gets the acEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of turn on/off AC.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getAcEnableAvailable() {
+ return getBoolean(KEY_AC_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the acMaxEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param acMaxEnableAvailable
+ * Availability of the control of enable/disable air conditioning is ON on the maximum level.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setAcMaxEnableAvailable(Boolean acMaxEnableAvailable) {
+ setValue(KEY_AC_MAX_ENABLE_AVAILABLE, acMaxEnableAvailable);
+ }
+
+ /**
+ * Gets the acMaxEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of enable/disable air conditioning is ON on the maximum level.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getAcMaxEnableAvailable() {
+ return getBoolean(KEY_AC_MAX_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the circulateAirEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param circulateAirEnableAvailable
+ * Availability of the control of enable/disable circulate Air mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setCirculateAirEnableAvailable(Boolean circulateAirEnableAvailable) {
+ setValue(KEY_CIRCULATE_AIR_ENABLE_AVAILABLE, circulateAirEnableAvailable);
+ }
+
+ /**
+ * Gets the circulateAirEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of enable/disable circulate Air mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getCirculateAirEnableAvailable() {
+ return getBoolean(KEY_CIRCULATE_AIR_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the autoModeEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param autoModeEnableAvailable
+ * Availability of the control of enable/disable auto mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setAutoModeEnableAvailable(Boolean autoModeEnableAvailable) {
+ setValue(KEY_AUTO_MODE_ENABLE_AVAILABLE, autoModeEnableAvailable);
+ }
+
+ /**
+ * Gets the autoModeEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of enable/disable auto mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getAutoModeEnableAvailable() {
+ return getBoolean(KEY_AUTO_MODE_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the dualModeEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param dualModeEnableAvailable
+ * Availability of the control of enable/disable dual mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setDualModeEnableAvailable(Boolean dualModeEnableAvailable) {
+ setValue(KEY_DUAL_MODE_ENABLE_AVAILABLE, dualModeEnableAvailable);
+ }
+
+ /**
+ * Gets the dualModeEnableAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of enable/disable dual mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getDualModeEnableAvailable() {
+ return getBoolean(KEY_DUAL_MODE_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the defrostZoneAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param defrostZoneAvailable
+ * Availability of the control of defrost zones.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setDefrostZoneAvailable(Boolean defrostZoneAvailable) {
+ setValue(KEY_DEFROST_ZONE_AVAILABLE, defrostZoneAvailable);
+ }
+
+ /**
+ * Gets the defrostZoneAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of defrost zones.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getDefrostZoneAvailable() {
+ return getBoolean(KEY_DEFROST_ZONE_AVAILABLE);
+ }
+
+ /**
+ * Gets the List<DefrostZone> portion of the ClimateControlCapabilities class
+ *
+ * @return List<DefrostZone> - A set of all defrost zones that are controllable.
+ */
+ public List<DefrostZone> getDefrostZone() {
+ return (List<DefrostZone>) getObject(DefrostZone.class, KEY_DEFROST_ZONE);
+ }
+
+ /**
+ * Sets the defrostZone portion of the ClimateControlCapabilities class
+ *
+ * @param defrostZone
+ * A set of all defrost zones that are controllable.
+ */
+ public void setDefrostZone(List<DefrostZone> defrostZone) {
+ setValue(KEY_DEFROST_ZONE, defrostZone);
+ }
+
+ /**
+ * Sets the ventilationModeAvailable portion of the ClimateControlCapabilities class
+ *
+ * @param ventilationModeAvailable
+ * Availability of the control of air ventilation mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setVentilationModeAvailable(Boolean ventilationModeAvailable) {
+ setValue(KEY_VENTILATION_MODE_AVAILABLE, ventilationModeAvailable);
+ }
+
+ /**
+ * Gets the ventilationModeAvailable portion of the ClimateControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of air ventilation mode.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getVentilationModeAvailable() {
+ return getBoolean(KEY_VENTILATION_MODE_AVAILABLE);
+ }
+
+ /**
+ * Gets the List<VentilationMode> portion of the ClimateControlCapabilities class
+ *
+ * @return List<VentilationMode> - A set of all ventilation modes that are controllable.
+ */
+ public List<VentilationMode> getVentilationMode() {
+ return (List<VentilationMode>) getObject(VentilationMode.class, KEY_VENTILATION_MODE);
+ }
+
+ /**
+ * Sets the ventilationMode portion of the ClimateControlCapabilities class
+ *
+ * @param ventilationMode
+ * A set of all ventilation modes that are controllable.
+ */
+ public void setVentilationMode(List<VentilationMode> ventilationMode) {
+ setValue(KEY_VENTILATION_MODE, ventilationMode);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlData.java
new file mode 100644
index 000000000..0da8060f3
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ClimateControlData.java
@@ -0,0 +1,106 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import com.smartdevicelink.proxy.rpc.enums.DefrostZone;
+import com.smartdevicelink.proxy.rpc.enums.VentilationMode;
+import java.util.Hashtable;
+
+public class ClimateControlData extends RPCStruct{
+ public static final String KEY_FAN_SPEED= "fanSpeed";
+ public static final String KEY_CURRENT_TEMPERATURE= "currentTemperature";
+ public static final String KEY_DESIRED_TEMPERATURE= "desiredTemperature";
+ public static final String KEY_AC_ENABLE= "acEnable";
+ public static final String KEY_CIRCULATE_AIR_ENABLE= "circulateAirEnable";
+ public static final String KEY_AUTO_MODE_ENABLE= "autoModeEnable";
+ public static final String KEY_DEFROST_ZONE= "defrostZone";
+ public static final String KEY_DUAL_MODE_ENABLE= "dualModeEnable";
+ public static final String KEY_AC_MAX_ENABLE= "acMaxEnable";
+ public static final String KEY_VENTILATION_MODE= "ventilationMode";
+
+ public ClimateControlData() {
+ }
+
+ public ClimateControlData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ public void setFanSpeed(Integer fanSpeed) {
+ setValue(KEY_FAN_SPEED, fanSpeed);
+ }
+
+ public Integer getFanSpeed() {
+ return getInteger(KEY_FAN_SPEED);
+ }
+
+ public void setCurrentTemperature(Temperature currentTemperature) {
+ setValue(KEY_CURRENT_TEMPERATURE, currentTemperature);
+ }
+
+ public Temperature getCurrentTemperature() {
+ return (Temperature) getObject(Temperature.class, KEY_CURRENT_TEMPERATURE);
+ }
+
+ public void setDesiredTemperature(Temperature desiredTemperature) {
+ setValue(KEY_DESIRED_TEMPERATURE, desiredTemperature);
+ }
+
+ public Temperature getDesiredTemperature() {
+ return (Temperature) getObject(Temperature.class, KEY_DESIRED_TEMPERATURE);
+ }
+
+ public void setAcEnable(Boolean acEnable) {
+ setValue(KEY_AC_ENABLE, acEnable);
+ }
+
+ public Boolean getAcEnable() {
+ return getBoolean(KEY_AC_ENABLE);
+ }
+
+ public void setCirculateAirEnable(Boolean circulateAirEnable) {
+ setValue(KEY_CIRCULATE_AIR_ENABLE, circulateAirEnable);
+ }
+
+ public Boolean getCirculateAirEnable() {
+ return getBoolean(KEY_CIRCULATE_AIR_ENABLE);
+ }
+
+ public void setAutoModeEnable(Boolean autoModeEnable) {
+ setValue(KEY_AUTO_MODE_ENABLE, autoModeEnable);
+ }
+
+ public Boolean getAutoModeEnable() {
+ return getBoolean(KEY_AUTO_MODE_ENABLE);
+ }
+
+ public void setDefrostZone(DefrostZone defrostZone) {
+ setValue(KEY_DEFROST_ZONE, defrostZone);
+ }
+
+ public DefrostZone getDefrostZone() {
+ return (DefrostZone) getObject(DefrostZone.class, KEY_DEFROST_ZONE);
+ }
+
+ public void setDualModeEnable(Boolean dualModeEnable) {
+ setValue(KEY_DUAL_MODE_ENABLE, dualModeEnable);
+ }
+
+ public Boolean getDualModeEnable() {
+ return getBoolean(KEY_DUAL_MODE_ENABLE);
+ }
+
+ public void setAcMaxEnable(Boolean acMaxEnable) {
+ setValue(KEY_AC_MAX_ENABLE, acMaxEnable);
+ }
+
+ public Boolean getAcMaxEnable() {
+ return getBoolean(KEY_AC_MAX_ENABLE);
+ }
+
+ public void setVentilationMode(VentilationMode ventilationMode) {
+ setValue(KEY_VENTILATION_MODE, ventilationMode);
+ }
+
+ public VentilationMode getVentilationMode() {
+ return (VentilationMode) getObject(VentilationMode.class, KEY_VENTILATION_MODE);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleData.java
new file mode 100644
index 000000000..53108b4fb
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleData.java
@@ -0,0 +1,79 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCRequest;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+import java.util.Hashtable;
+
+/**
+ * Read the current status value of specified remote control module (type). In addition,
+ * When subscribe=true, subscribes for specific remote control module data items;
+ * When subscribe=false, un-subscribes for specific remote control module data items.
+ * Once subscribed, the application will be notified by the onInteriorVehicleData notification
+ * whenever new data is available for the module.
+ */
+public class GetInteriorVehicleData extends RPCRequest {
+ public static final String KEY_MODULE_TYPE = "moduleType";
+ public static final String KEY_SUBSCRIBE = "subscribe";
+
+ /**
+ * Constructs a new GetInteriorVehicleData object
+ */
+ public GetInteriorVehicleData() {
+ super(FunctionID.GET_INTERIOR_VEHICLE_DATA.toString());
+ }
+
+ /**
+ * <p>Constructs a new GetInteriorVehicleData object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public GetInteriorVehicleData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Gets the ModuleType
+ *
+ * @return ModuleType - The type of a RC module to retrieve module data from the vehicle.
+ * In the future, this should be the Identification of a module.
+ */
+ public ModuleType getModuleType() {
+ return (ModuleType) getObject(ModuleType.class, KEY_MODULE_TYPE);
+ }
+
+ /**
+ * Sets a ModuleType
+ *
+ * @param moduleType
+ * The type of a RC module to retrieve module data from the vehicle.
+ * In the future, this should be the Identification of a module.
+ */
+ public void setModuleType(ModuleType moduleType) {
+ setParameters(KEY_MODULE_TYPE, moduleType);
+ }
+
+ /**
+ * Sets subscribe parameter
+ *
+ * @param subscribe
+ * If subscribe is true, the head unit will register onInteriorVehicleData notifications for the requested moduelType.
+ * If subscribe is false, the head unit will unregister onInteriorVehicleData notifications for the requested moduelType.
+ */
+ public void setSubscribe(Boolean subscribe) {
+ setParameters(KEY_SUBSCRIBE, subscribe);
+ }
+
+ /**
+ * Gets subscribe parameter
+ *
+ * @return Boolean - If subscribe is true, the head unit will register onInteriorVehicleData notifications for the requested moduelType.
+ * If subscribe is false, the head unit will unregister onInteriorVehicleData notifications for the requested moduelType.
+ */
+ public Boolean getSubscribe() {
+ return getBoolean(KEY_SUBSCRIBE);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleDataResponse.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleDataResponse.java
new file mode 100644
index 000000000..0e74001f6
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/GetInteriorVehicleDataResponse.java
@@ -0,0 +1,70 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCResponse;
+import java.util.Hashtable;
+
+public class GetInteriorVehicleDataResponse extends RPCResponse {
+ public static final String KEY_MODULE_DATA = "moduleData";
+ public static final String KEY_IS_SUBSCRIBED = "isSubscribed";
+
+ /**
+ * Constructs a new GetInteriorVehicleDataResponse object
+ */
+ public GetInteriorVehicleDataResponse() {
+ super(FunctionID.GET_INTERIOR_VEHICLE_DATA.toString());
+ }
+
+ /**
+ * <p>Constructs a new GetInteriorVehicleDataResponse object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public GetInteriorVehicleDataResponse(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Gets the moduleData
+ *
+ * @return ModuleData
+ */
+ public ModuleData getModuleData() {
+ return (ModuleData) getObject(ModuleData.class, KEY_MODULE_DATA);
+ }
+
+ /**
+ * Sets the moduleData
+ *
+ * @param moduleData
+ */
+ public void setModuleData(ModuleData moduleData) {
+ setParameters(KEY_MODULE_DATA, moduleData);
+ }
+
+ /**
+ * Sets isSubscribed parameter
+ *
+ * @param isSubscribed
+ * It is a conditional-mandatory parameter: must be returned in case "subscribe" parameter was present in the related request.
+ * If "true" - the "moduleType" from request is successfully subscribed and the head unit will send onInteriorVehicleData notifications for the moduleType.
+ * If "false" - the "moduleType" from request is either unsubscribed or failed to subscribe.
+ * */
+ public void setIsSubscribed(Boolean isSubscribed) {
+ setParameters(KEY_IS_SUBSCRIBED, isSubscribed);
+ }
+
+ /**
+ * Gets isSubscribed parameter
+ *
+ * @return Boolean - It is a conditional-mandatory parameter: must be returned in case "subscribe" parameter was present in the related request.
+ * If "true" - the "moduleType" from request is successfully subscribed and the head unit will send onInteriorVehicleData notifications for the moduleType.
+ * If "false" - the "moduleType" from request is either unsubscribed or failed to subscribe.
+ * */
+ public Boolean getIsSubscribed() {
+ return getBoolean(KEY_IS_SUBSCRIBED);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/HMICapabilities.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/HMICapabilities.java
index 77c534c9f..8f4cdfe66 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/HMICapabilities.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/HMICapabilities.java
@@ -8,6 +8,7 @@ public class HMICapabilities extends RPCStruct{
public static final String KEY_NAVIGATION = "navigation";
public static final String KEY_PHONE_CALL = "phoneCall";
public static final String KEY_VIDEO_STREAMING = "videoStreaming";
+ public static final String KEY_REMOTE_CONTROL = "remoteControl";
public HMICapabilities() { }
@@ -51,5 +52,17 @@ public class HMICapabilities extends RPCStruct{
setValue(KEY_VIDEO_STREAMING, available);
}
+ public boolean isRemoteControlAvailable(){
+ Object available = getValue(KEY_REMOTE_CONTROL);
+ if(available == null){
+ return false;
+ }
+ return (Boolean)available;
+ }
+
+ public void setRemoteControlAvailable(Boolean available){
+ setValue(KEY_REMOTE_CONTROL, available);
+ }
+
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ImageResolution.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ImageResolution.java
index d9c85eb8f..5858a45d0 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ImageResolution.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ImageResolution.java
@@ -76,4 +76,10 @@ public class ImageResolution extends RPCStruct {
public Integer getResolutionHeight() {
return getInteger(KEY_RESOLUTION_HEIGHT);
}
+
+ @Override
+ public String toString() {
+ return "width=" + String.valueOf(getResolutionWidth()) +
+ ", height=" + String.valueOf(getResolutionHeight());
+ }
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ModuleData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ModuleData.java
new file mode 100644
index 000000000..e04ab1ad5
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/ModuleData.java
@@ -0,0 +1,75 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import com.smartdevicelink.proxy.rpc.enums.ModuleType;
+import java.util.Hashtable;
+
+public class ModuleData extends RPCStruct{
+ public static final String KEY_MODULE_TYPE= "moduleType";
+ public static final String KEY_RADIO_CONTROL_DATA = "radioControlData";
+ public static final String KEY_CLIMATE_CONTROL_DATA = "climateControlData";
+
+ public ModuleData() {
+ }
+
+ public ModuleData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the moduleType portion of the ModuleData class
+ *
+ * @param moduleType
+ * The moduleType indicates which type of data should be changed and identifies which data object exists in this struct.
+ * For example, if the moduleType is CLIMATE then a "climateControlData" should exist
+ */
+ public void setModuleType(ModuleType moduleType) {
+ setValue(KEY_MODULE_TYPE, moduleType);
+ }
+
+ /**
+ * Gets the moduleType portion of the ModuleData class
+ *
+ * @return ModuleType - The moduleType indicates which type of data should be changed and identifies which data object exists in this struct.
+ * For example, if the moduleType is CLIMATE then a "climateControlData" should exist.
+ */
+ public ModuleType getModuleType() {
+ return (ModuleType) getObject(ModuleType.class, KEY_MODULE_TYPE);
+ }
+
+ /**
+ * Sets the radioControlData portion of the ModuleData class
+ *
+ * @param radioControlData
+ */
+ public void setRadioControlData(RadioControlData radioControlData) {
+ setValue(KEY_RADIO_CONTROL_DATA, radioControlData);
+ }
+
+ /**
+ * Gets the radioControlData portion of the ModuleData class
+ *
+ * @return RadioControlData
+ */
+ public RadioControlData getRadioControlData() {
+ return (RadioControlData) getObject(RadioControlData.class, KEY_RADIO_CONTROL_DATA);
+ }
+
+ /**
+ * Sets the climateControlData portion of the ModuleData class
+ *
+ * @param climateControlData
+ */
+ public void setClimateControlData(ClimateControlData climateControlData) {
+ setValue(KEY_CLIMATE_CONTROL_DATA, climateControlData);
+ }
+
+ /**
+ * Gets the climateControlData portion of the ModuleData class
+ *
+ * @return ClimateControlData
+ */
+ public ClimateControlData getClimateControlData() {
+ return (ClimateControlData) getObject(ClimateControlData.class, KEY_CLIMATE_CONTROL_DATA);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/OnInteriorVehicleData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/OnInteriorVehicleData.java
new file mode 100644
index 000000000..61e9ee17a
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/OnInteriorVehicleData.java
@@ -0,0 +1,47 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCNotification;
+
+import java.util.Hashtable;
+
+public class OnInteriorVehicleData extends RPCNotification {
+ public static final String KEY_MODULE_DATA = "moduleData";
+
+ /**
+ * Constructs a new OnInteriorVehicleData object
+ */
+ public OnInteriorVehicleData() {
+ super(FunctionID.ON_INTERIOR_VEHICLE_DATA.toString());
+ }
+
+ /**
+ * <p>Constructs a new OnInteriorVehicleData object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public OnInteriorVehicleData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Gets the moduleData
+ *
+ * @return ModuleData
+ */
+ public ModuleData getModuleData() {
+ return (ModuleData) getObject(ModuleData.class, KEY_MODULE_DATA);
+ }
+
+ /**
+ * Sets the moduleData
+ *
+ * @param moduleData
+ */
+ public void setModuleData(ModuleData moduleData) {
+ setParameters(KEY_MODULE_DATA, moduleData);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlCapabilities.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlCapabilities.java
new file mode 100644
index 000000000..3acfe77a9
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlCapabilities.java
@@ -0,0 +1,236 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import java.util.Hashtable;
+
+/**
+ * Contains information about a radio control module's capabilities.
+ */
+public class RadioControlCapabilities extends RPCStruct{
+ public static final String KEY_MODULE_NAME= "moduleName";
+ public static final String KEY_RADIO_ENABLE_AVAILABLE= "radioEnableAvailable";
+ public static final String KEY_RADIO_BAND_AVAILABLE= "radioBandAvailable";
+ public static final String KEY_RADIO_FREQUENCY_AVAILABLE= "radioFrequencyAvailable";
+ public static final String KEY_HD_CHANNEL_AVAILABLE= "hdChannelAvailable";
+ public static final String KEY_RDS_DATA_AVAILABLE= "rdsDataAvailable";
+ public static final String KEY_AVAILABLE_HDS_AVAILABLE= "availableHDsAvailable";
+ public static final String KEY_STATE_AVAILABLE= "stateAvailable";
+ public static final String KEY_SIGNAL_STRENGTH_AVAILABLE= "signalStrengthAvailable";
+ public static final String KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE= "signalChangeThresholdAvailable";
+
+ public RadioControlCapabilities() {
+ }
+
+ public RadioControlCapabilities(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the moduleName portion of the RadioControlCapabilities class
+ *
+ * @param moduleName
+ * The short friendly name of the climate control module.
+ * It should not be used to identify a module by mobile application.
+ */
+ public void setModuleName(String moduleName) {
+ setValue(KEY_MODULE_NAME, moduleName);
+ }
+
+ /**
+ * Gets the moduleName portion of the RadioControlCapabilities class
+ *
+ * @return String - Short friendly name of the climate control module.
+ */
+ public String getModuleName() {
+ return getString(KEY_MODULE_NAME);
+ }
+
+ /**
+ * Sets the radioEnableAvailable portion of the RadioControlCapabilities class
+ *
+ * @param radioEnableAvailable
+ * Availability of the control of enable/disable radio.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setRadioEnableAvailable(Boolean radioEnableAvailable) {
+ setValue(KEY_RADIO_ENABLE_AVAILABLE, radioEnableAvailable);
+ }
+
+ /**
+ * Gets the radioEnableAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of enable/disable radio.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getRadioEnableAvailable() {
+ return getBoolean(KEY_RADIO_ENABLE_AVAILABLE);
+ }
+
+ /**
+ * Sets the radioBandAvailable portion of the RadioControlCapabilities class
+ *
+ * @param radioBandAvailable
+ * Availability of the control of radio band.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setRadioBandAvailable(Boolean radioBandAvailable) {
+ setValue(KEY_RADIO_BAND_AVAILABLE, radioBandAvailable);
+ }
+
+ /**
+ * Gets the radioBandAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of radio band.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getRadioBandAvailable() {
+ return getBoolean(KEY_RADIO_BAND_AVAILABLE);
+ }
+
+ /**
+ * Sets the radioFrequencyAvailable portion of the RadioControlCapabilities class
+ *
+ * @param radioFrequencyAvailable
+ * Availability of the control of radio frequency.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setRadioFrequencyAvailable(Boolean radioFrequencyAvailable) {
+ setValue(KEY_RADIO_FREQUENCY_AVAILABLE, radioFrequencyAvailable);
+ }
+
+ /**
+ * Gets the radioFrequencyAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of radio frequency.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getRadioFrequencyAvailable() {
+ return getBoolean(KEY_RADIO_FREQUENCY_AVAILABLE);
+ }
+
+ /**
+ * Sets the hdChannelAvailable portion of the RadioControlCapabilities class
+ *
+ * @param hdChannelAvailable
+ * Availability of the control of HD radio channel.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setHdChannelAvailable(Boolean hdChannelAvailable) {
+ setValue(KEY_HD_CHANNEL_AVAILABLE, hdChannelAvailable);
+ }
+
+ /**
+ * Gets the hdChannelAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the control of HD radio channel.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getHdChannelAvailable() {
+ return getBoolean(KEY_HD_CHANNEL_AVAILABLE);
+ }
+
+ /**
+ * Sets the rdsDataAvailable portion of the RadioControlCapabilities class
+ *
+ * @param rdsDataAvailable
+ * Availability of the getting Radio Data System (RDS) data.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setRdsDataAvailable(Boolean rdsDataAvailable) {
+ setValue(KEY_RDS_DATA_AVAILABLE, rdsDataAvailable);
+ }
+
+ /**
+ * Gets the rdsDataAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the getting Radio Data System (RDS) data.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getRdsDataAvailable() {
+ return getBoolean(KEY_RDS_DATA_AVAILABLE);
+ }
+
+ /**
+ * Sets the availableHDsAvailable portion of the RadioControlCapabilities class
+ *
+ * @param availableHDsAvailable
+ * Availability of the getting the number of available HD channels.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setAvailableHDsAvailable(Boolean availableHDsAvailable) {
+ setValue(KEY_AVAILABLE_HDS_AVAILABLE, availableHDsAvailable);
+ }
+
+ /**
+ * Gets the availableHDsAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the getting the number of available HD channels.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getAvailableHDsAvailable() {
+ return getBoolean(KEY_AVAILABLE_HDS_AVAILABLE);
+ }
+
+ /**
+ * Sets the stateAvailable portion of the RadioControlCapabilities class
+ *
+ * @param stateAvailable
+ * Availability of the getting the Radio state.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setStateAvailable(Boolean stateAvailable) {
+ setValue(KEY_STATE_AVAILABLE, stateAvailable);
+ }
+
+ /**
+ * Gets the stateAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the getting the Radio state.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getStateAvailable() {
+ return getBoolean(KEY_STATE_AVAILABLE);
+ }
+
+ /**
+ * Sets the signalStrengthAvailable portion of the RadioControlCapabilities class
+ *
+ * @param signalStrengthAvailable
+ * Availability of the getting the signal strength.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setSignalStrengthAvailable(Boolean signalStrengthAvailable) {
+ setValue(KEY_SIGNAL_STRENGTH_AVAILABLE, signalStrengthAvailable);
+ }
+
+ /**
+ * Gets the signalStrengthAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the getting the signal strength.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getSignalStrengthAvailable() {
+ return getBoolean(KEY_SIGNAL_STRENGTH_AVAILABLE);
+ }
+
+ /**
+ * Sets the signalChangeThresholdAvailable portion of the RadioControlCapabilities class
+ *
+ * @param signalChangeThresholdAvailable
+ * Availability of the getting the signal Change Threshold.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public void setSignalChangeThresholdAvailable(Boolean signalChangeThresholdAvailable) {
+ setValue(KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE, signalChangeThresholdAvailable);
+ }
+
+ /**
+ * Gets the signalChangeThresholdAvailable portion of the RadioControlCapabilities class
+ *
+ * @return Boolean - Availability of the getting the signal Change Threshold.
+ * True: Available, False: Not Available, Not present: Not Available.
+ */
+ public Boolean getSignalChangeThresholdAvailable() {
+ return getBoolean(KEY_SIGNAL_CHANGE_THRESHOLD_AVAILABLE);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlData.java
new file mode 100644
index 000000000..90d8a9de0
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RadioControlData.java
@@ -0,0 +1,220 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import com.smartdevicelink.proxy.rpc.enums.RadioBand;
+import com.smartdevicelink.proxy.rpc.enums.RadioState;
+import java.util.Hashtable;
+
+/**
+ * Include information (both read-only and changeable data) about a
+ * remote control radio module.
+ */
+public class RadioControlData extends RPCStruct{
+ public static final String KEY_FREQUENCY_INTEGER= "frequencyInteger";
+ public static final String KEY_FREQUENCY_FRACTION= "frequencyFraction";
+ public static final String KEY_BAND= "band";
+ public static final String KEY_RDS_DATA= "rdsData";
+ public static final String KEY_AVAILABLE_HDS= "availableHDs";
+ public static final String KEY_HD_CHANNEL= "hdChannel";
+ public static final String KEY_SIGNAL_STRENGTH= "signalStrength";
+ public static final String KEY_SIGNAL_CHANGE_THRESHOLD= "signalChangeThreshold";
+ public static final String KEY_RADIO_ENABLE= "radioEnable";
+ public static final String KEY_STATE= "state";
+
+ public RadioControlData() {
+ }
+
+ public RadioControlData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the frequencyInteger portion of the RadioControlData class
+ *
+ * @param frequencyInteger
+ * The integer part of the frequency i.e. for 101.7 this value should be 101
+ */
+ public void setFrequencyInteger(Integer frequencyInteger) {
+ setValue(KEY_FREQUENCY_INTEGER, frequencyInteger);
+ }
+
+ /**
+ * Gets the frequencyInteger portion of the RadioControlData class
+ *
+ * @return Integer - The integer part of the frequency i.e. for 101.7 this value should be 101.
+ */
+ public Integer getFrequencyInteger() {
+ return getInteger(KEY_FREQUENCY_INTEGER);
+ }
+
+ /**
+ * Sets the frequencyFraction portion of the RadioControlData class
+ *
+ * @param frequencyFraction
+ * The fractional part of the frequency i.e. for 101.7 is 7.
+ */
+ public void setFrequencyFraction(Integer frequencyFraction) {
+ setValue(KEY_FREQUENCY_FRACTION, frequencyFraction);
+ }
+
+ /**
+ * Gets the frequencyFraction portion of the RadioControlData class
+ *
+ * @return Integer - The fractional part of the frequency i.e. for 101.7 is 7.
+ */
+ public Integer getFrequencyFraction() {
+ return getInteger(KEY_FREQUENCY_FRACTION);
+ }
+
+ /**
+ * Sets the band portion of the RadioControlData class
+ *
+ * @param band
+ * The radio band (AM|FM|XM) of the radio tuner.
+ */
+ public void setBand(RadioBand band) {
+ setValue(KEY_BAND, band);
+ }
+
+ /**
+ * Gets the band portion of the RadioControlData class
+ *
+ * @return RadioBand - The radio band (AM|FM|XM) of the radio tuner.
+ */
+ public RadioBand getBand() {
+ return (RadioBand) getObject(RadioBand.class, KEY_BAND);
+ }
+
+ /**
+ * Sets the rdsData portion of the RadioControlData class
+ *
+ * @param rdsData
+ * Read only parameter. See RdsData data type for details.
+ */
+ public void setRdsData(RdsData rdsData) {
+ setValue(KEY_RDS_DATA, rdsData);
+ }
+
+ /**
+ * Gets the rdsData portion of the RadioControlData class
+ *
+ * @return RdsData - Read only parameter. See RdsData data type for details.
+ */
+ public RdsData getRdsData() {
+ return (RdsData) getObject(RdsData.class, KEY_RDS_DATA);
+ }
+
+ /**
+ * Sets the availableHDs portion of the RadioControlData class
+ *
+ * @param availableHDs
+ * Number of HD sub-channels if available.
+ */
+ public void setAvailableHDs(Integer availableHDs) {
+ setValue(KEY_AVAILABLE_HDS, availableHDs);
+ }
+
+ /**
+ * Gets the availableHDs portion of the RadioControlData class
+ *
+ * @return Integer - Number of HD sub-channels if available.
+ */
+ public Integer getAvailableHDs() {
+ return getInteger(KEY_AVAILABLE_HDS);
+ }
+
+ /**
+ * Sets the hdChannel portion of the RadioControlData class
+ *
+ * @param hdChannel
+ * Current HD sub-channel if available.
+ */
+ public void setHdChannel(Integer hdChannel) {
+ setValue(KEY_HD_CHANNEL, hdChannel);
+ }
+
+ /**
+ * Gets the hdChannel portion of the RadioControlData class
+ *
+ * @return Integer - Current HD sub-channel if available.
+ */
+ public Integer getHdChannel() {
+ return getInteger(KEY_HD_CHANNEL);
+ }
+
+ /**
+ * Sets the signalStrength portion of the RadioControlData class
+ *
+ * @param signalStrength
+ * Read only parameter. Indicates the strength of receiving radio signal in current frequency.
+ */
+ public void setSignalStrength(Integer signalStrength) {
+ setValue(KEY_SIGNAL_STRENGTH, signalStrength);
+ }
+
+ /**
+ * Gets the signalStrength portion of the RadioControlData class
+ *
+ * @return Integer - Read only parameter. Indicates the strength of receiving radio signal in current frequency.
+ */
+ public Integer getSignalStrength() {
+ return getInteger(KEY_SIGNAL_STRENGTH);
+ }
+
+ /**
+ * Sets the signalChangeThreshold portion of the RadioControlData class
+ *
+ * @param signalChangeThreshold
+ * If the signal strength falls below the set value for this parameter, the radio will tune to an alternative frequency.
+ */
+ public void setSignalChangeThreshold(Integer signalChangeThreshold) {
+ setValue(KEY_SIGNAL_CHANGE_THRESHOLD, signalChangeThreshold);
+ }
+
+ /**
+ * Gets the signalChangeThreshold portion of the RadioControlData class
+ *
+ * @return Integer - If the signal strength falls below the set value for this parameter, the radio will tune to an alternative frequency.
+ */
+ public Integer getSignalChangeThreshold() {
+ return getInteger(KEY_SIGNAL_CHANGE_THRESHOLD);
+ }
+
+ /**
+ * Sets the radioEnable portion of the RadioControlData class
+ *
+ * @param radioEnable
+ * True if the radio is on, false is the radio is off.
+ */
+ public void setRadioEnable(Boolean radioEnable) {
+ setValue(KEY_RADIO_ENABLE, radioEnable);
+ }
+
+ /**
+ * Gets the radioEnable portion of the RadioControlData class
+ *
+ * @return Boolean - True if the radio is on, false is the radio is off.
+ */
+ public Boolean getRadioEnable() {
+ return getBoolean(KEY_RADIO_ENABLE);
+ }
+
+ /**
+ * Sets the state portion of the RadioControlData class
+ *
+ * @param state
+ * Read only parameter. See RadioState data type for details.
+ */
+ public void setState(RadioState state) {
+ setValue(KEY_STATE, state);
+ }
+
+ /**
+ * Gets the state portion of the RadioControlData class
+ *
+ * @return RadioState - Read only parameter. See RadioState data type for details.
+ */
+ public RadioState getState() {
+ return (RadioState) getObject(RadioState.class, KEY_STATE);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RdsData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RdsData.java
new file mode 100644
index 000000000..2ed934865
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RdsData.java
@@ -0,0 +1,180 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+
+import java.util.Hashtable;
+
+/**
+ * Include the data defined in Radio Data System, which is a communications protocol standard
+ * for embedding small amounts of digital information in conventional FM radio broadcasts.
+ */
+public class RdsData extends RPCStruct{
+ public static final String KEY_PS= "PS";
+ public static final String KEY_RT= "RT";
+ public static final String KEY_CT= "CT";
+ public static final String KEY_PI= "PI";
+ public static final String KEY_PTY= "PTY";
+ public static final String KEY_TP= "TP";
+ public static final String KEY_TA= "TA";
+ public static final String KEY_REG= "REG";
+
+ public RdsData() {
+ }
+
+ public RdsData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the programService portion of the RdsData class
+ *
+ * @param programService
+ * Program Service Name.
+ */
+ public void setProgramService(String programService) {
+ setValue(KEY_PS, programService);
+ }
+
+ /**
+ * Gets the programService portion of the RdsData class
+ *
+ * @return String - Program Service Name.
+ */
+ public String getProgramService() {
+ return getString(KEY_PS);
+ }
+
+ /**
+ * Sets the radioText portion of the RdsData class
+ *
+ * @param radioText
+ * Radio Text.
+ */
+ public void setRadioText(String radioText) {
+ setValue(KEY_RT, radioText);
+ }
+
+ /**
+ * Gets the radioText portion of the RdsData class
+ *
+ * @return String - Radio Text.
+ */
+ public String getRadioText() {
+ return getString(KEY_RT);
+ }
+
+ /**
+ * Sets the clockText portion of the RdsData class
+ *
+ * @param clockText
+ * The clock text in UTC format as YYYY-MM-DDThh:mm:ss.sTZD.
+ */
+ public void setClockText(String clockText) {
+ setValue(KEY_CT, clockText);
+ }
+
+ /**
+ * Gets the clockText portion of the RdsData class
+ *
+ * @return String - The clock text in UTC format as YYYY-MM-DDThh:mm:ss.sTZD.
+ */
+ public String getClockText() {
+ return getString(KEY_CT);
+ }
+
+ /**
+ * Sets the programIdentification portion of the RdsData class
+ *
+ * @param programIdentification
+ * Program Identification - the call sign for the radio station.
+ */
+ public void setProgramIdentification(String programIdentification) {
+ setValue(KEY_PI, programIdentification);
+ }
+
+ /**
+ * Gets the programIdentification portion of the RdsData class
+ *
+ * @return String - Program Identification - the call sign for the radio station.
+ */
+ public String getProgramIdentification() {
+ return getString(KEY_PI);
+ }
+
+ /**
+ * Sets the region portion of the RdsData class
+ *
+ * @param region
+ * Region.
+ */
+ public void setRegion(String region) {
+ setValue(KEY_REG, region);
+ }
+
+ /**
+ * Gets the region portion of the RdsData class
+ *
+ * @return String - Region.
+ */
+ public String getRegion() {
+ return getString(KEY_REG);
+ }
+
+ /**
+ * Sets the trafficProgram portion of the RdsData class
+ *
+ * @param trafficProgram
+ * Traffic Program Identification - Identifies a station that offers traffic.
+ */
+ public void setTrafficProgram(Boolean trafficProgram) {
+ setValue(KEY_TP, trafficProgram);
+ }
+
+ /**
+ * Gets the trafficProgram portion of the RdsData class
+ *
+ * @return Boolean - Traffic Program Identification - Identifies a station that offers traffic.
+ */
+ public Boolean getTrafficProgram() {
+ return getBoolean(KEY_TP);
+ }
+
+ /**
+ * Sets the trafficAnnouncement portion of the RdsData class
+ *
+ * @param trafficAnnouncement
+ * Traffic Announcement Identification - Indicates an ongoing traffic announcement.
+ */
+ public void setTrafficAnnouncement(Boolean trafficAnnouncement) {
+ setValue(KEY_TA, trafficAnnouncement);
+ }
+
+ /**
+ * Gets the trafficAnnouncement portion of the RdsData class
+ *
+ * @return Boolean - Traffic Announcement Identification - Indicates an ongoing traffic announcement.
+ */
+ public Boolean getTrafficAnnouncement() {
+ return getBoolean(KEY_TA);
+ }
+
+ /**
+ * Sets the programType portion of the RdsData class
+ *
+ * @param programType
+ * The program type - The region should be used to differentiate between EU and North America program types.
+ */
+ public void setProgramType(Integer programType) {
+ setValue(KEY_PTY, programType);
+ }
+
+ /**
+ * Gets the programType portion of the RdsData class
+ *
+ * @return Integer - The program type.
+ * The region should be used to differentiate between EU and North America program types.
+ */
+ public Integer getProgramType() {
+ return getInteger(KEY_PTY);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RemoteControlCapabilities.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RemoteControlCapabilities.java
new file mode 100644
index 000000000..ec51aa633
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/RemoteControlCapabilities.java
@@ -0,0 +1,82 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import java.util.Hashtable;
+import java.util.List;
+
+public class RemoteControlCapabilities extends RPCStruct{
+ public static final String KEY_CLIMATE_CONTROL_CAPABILITIES= "climateControlCapabilities";
+ public static final String KEY_RADIO_CONTROL_CAPABILITIES = "radioControlCapabilities";
+ public static final String KEY_BUTTON_CAPABILITIES = "buttonCapabilities";
+
+ public RemoteControlCapabilities() {
+ }
+
+ public RemoteControlCapabilities(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the climateControlCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @param climateControlCapabilities
+ * If included, the platform supports RC climate controls.
+ * For this baseline version, maxsize=1. i.e. only one climate control module is supported.
+ */
+ public void setClimateControlCapabilities(List<ClimateControlCapabilities> climateControlCapabilities) {
+ setValue(KEY_CLIMATE_CONTROL_CAPABILITIES, climateControlCapabilities);
+ }
+
+ /**
+ * Gets the climateControlCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @return List<ClimateControlCapabilities>
+ * If included, the platform supports RC climate controls.
+ * For this baseline version, maxsize=1. i.e. only one climate control module is supported.
+ */
+ public List<ClimateControlCapabilities> getClimateControlCapabilities() {
+ return (List<ClimateControlCapabilities>) getObject(ClimateControlCapabilities.class, KEY_CLIMATE_CONTROL_CAPABILITIES);
+ }
+
+ /**
+ * Sets the radioControlCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @param radioControlCapabilities
+ * If included, the platform supports RC climate controls.
+ * For this baseline version, maxsize=1. i.e. only one radio control module is supported.
+ */
+ public void setRadioControlCapabilities(List<RadioControlCapabilities> radioControlCapabilities) {
+ setValue(KEY_RADIO_CONTROL_CAPABILITIES, radioControlCapabilities);
+ }
+
+ /**
+ * Gets the radioControlCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @return List<RadioControlCapabilities>
+ * If included, the platform supports RC climate controls.
+ * For this baseline version, maxsize=1. i.e. only one radio control module is supported.
+ */
+ public List<RadioControlCapabilities> getRadioControlCapabilities() {
+ return (List<RadioControlCapabilities>) getObject(RadioControlCapabilities.class, KEY_RADIO_CONTROL_CAPABILITIES);
+ }
+
+ /**
+ * Sets the buttonCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @param buttonCapabilities
+ * If included, the platform supports RC button controls with the included button names.
+ */
+ public void setButtonCapabilities(List<ButtonCapabilities> buttonCapabilities) {
+ setValue(KEY_BUTTON_CAPABILITIES, buttonCapabilities);
+ }
+
+ /**
+ * Gets the buttonCapabilities portion of the RemoteControlCapabilities class
+ *
+ * @return List<ButtonCapabilities>
+ * If included, the platform supports RC button controls with the included button names.
+ */
+ public List<ButtonCapabilities> getButtonCapabilities() {
+ return (List<ButtonCapabilities>) getObject(ButtonCapabilities.class, KEY_BUTTON_CAPABILITIES);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleData.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleData.java
new file mode 100644
index 000000000..75077e3cb
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleData.java
@@ -0,0 +1,51 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCRequest;
+
+import java.util.Hashtable;
+
+/**
+ * This function allows a remote control type mobile application change the settings
+ * of a specific remote control module.
+ */
+public class SetInteriorVehicleData extends RPCRequest {
+ public static final String KEY_MODULE_DATA = "moduleData";
+
+ /**
+ * Constructs a new SetInteriorVehicleData object
+ */
+ public SetInteriorVehicleData() {
+ super(FunctionID.SET_INTERIOR_VEHICLE_DATA.toString());
+ }
+
+ /**
+ * <p>Constructs a new SetInteriorVehicleData object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public SetInteriorVehicleData(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the moduleData
+ *
+ * @param moduleData
+ */
+ public void setModuleData(ModuleData moduleData) {
+ setParameters(KEY_MODULE_DATA, moduleData);
+ }
+
+ /**
+ * Gets the moduleData
+ *
+ * @return ModuleData
+ */
+ public ModuleData getModuleData() {
+ return (ModuleData) getObject(ModuleData.class, KEY_MODULE_DATA);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleDataResponse.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleDataResponse.java
new file mode 100644
index 000000000..6a7079735
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SetInteriorVehicleDataResponse.java
@@ -0,0 +1,47 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.protocol.enums.FunctionID;
+import com.smartdevicelink.proxy.RPCResponse;
+
+import java.util.Hashtable;
+
+public class SetInteriorVehicleDataResponse extends RPCResponse {
+ public static final String KEY_MODULE_DATA = "moduleData";
+
+ /**
+ * Constructs a new SetInteriorVehicleDataResponse object
+ */
+ public SetInteriorVehicleDataResponse() {
+ super(FunctionID.SET_INTERIOR_VEHICLE_DATA.toString());
+ }
+
+ /**
+ * <p>Constructs a new SetInteriorVehicleDataResponse object indicated by the
+ * Hashtable parameter</p>
+ *
+ *
+ * @param hash
+ * The Hashtable to use
+ */
+ public SetInteriorVehicleDataResponse(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Gets the moduleData
+ *
+ * @return ModuleData
+ */
+ public ModuleData getModuleData() {
+ return (ModuleData) getObject(ModuleData.class, KEY_MODULE_DATA);
+ }
+
+ /**
+ * Sets the moduleData
+ *
+ * @param moduleData
+ */
+ public void setModuleData(ModuleData moduleData) {
+ setParameters(KEY_MODULE_DATA, moduleData);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SystemCapability.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SystemCapability.java
index c7ea47ce6..386f28b45 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SystemCapability.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/SystemCapability.java
@@ -14,6 +14,7 @@ public class SystemCapability extends RPCStruct {
public static final String KEY_NAVIGATION_CAPABILITY = "navigationCapability";
public static final String KEY_PHONE_CAPABILITY = "phoneCapability";
public static final String KEY_VIDEO_STREAMING_CAPABILITY = "videoStreamingCapability";
+ public static final String KEY_REMOTE_CONTROL_CAPABILITY = "remoteControlCapability";
public SystemCapability(){}
@@ -43,6 +44,8 @@ public class SystemCapability extends RPCStruct {
return (RPCStruct) getObject(PhoneCapability.class, KEY_PHONE_CAPABILITY);
} else if (type.equals(SystemCapabilityType.VIDEO_STREAMING)){
return (RPCStruct) getObject(VideoStreamingCapability.class, KEY_VIDEO_STREAMING_CAPABILITY);
+ }else if(type.equals(SystemCapabilityType.REMOTE_CONTROL)){
+ return (RPCStruct) getObject(RemoteControlCapabilities.class, KEY_REMOTE_CONTROL_CAPABILITY);
}else{
return null;
}
@@ -55,6 +58,8 @@ public class SystemCapability extends RPCStruct {
setValue(KEY_PHONE_CAPABILITY, capability);
}else if(type.equals(SystemCapabilityType.VIDEO_STREAMING)){
setValue(KEY_VIDEO_STREAMING_CAPABILITY, capability);
+ }else if(type.equals(SystemCapabilityType.REMOTE_CONTROL)){
+ setValue(KEY_REMOTE_CONTROL_CAPABILITY, capability);
}else{
return;
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/Temperature.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/Temperature.java
new file mode 100644
index 000000000..29fea734f
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/Temperature.java
@@ -0,0 +1,56 @@
+package com.smartdevicelink.proxy.rpc;
+
+import com.smartdevicelink.proxy.RPCStruct;
+import com.smartdevicelink.proxy.rpc.enums.TemperatureUnit;
+import com.smartdevicelink.util.SdlDataTypeConverter;
+
+import java.util.Hashtable;
+
+public class Temperature extends RPCStruct{
+ public static final String KEY_UNIT = "unit";
+ public static final String KEY_VALUE = "value";
+
+ public Temperature() { }
+ public Temperature(Hashtable<String, Object> hash) {
+ super(hash);
+ }
+
+ /**
+ * Sets the unit portion of the Temperature class
+ *
+ * @param unit
+ * Temperature Unit.
+ */
+ public void setUnit(TemperatureUnit unit) {
+ setValue(KEY_UNIT, unit);
+ }
+
+ /**
+ * Gets the unit portion of the Temperature class
+ *
+ * @return TemperatureUnit - Temperature Unit.
+ */
+ public TemperatureUnit getUnit() {
+ return (TemperatureUnit) getObject(TemperatureUnit.class, KEY_UNIT);
+ }
+
+ /**
+ * Gets the value portion of the Temperature class
+ *
+ * @return Float - Temperature Value in TemperatureUnit specified unit. Range depends on OEM and is not checked by SDL.
+ */
+ public Float getValue() {
+ Object value = getValue(KEY_VALUE);
+ return SdlDataTypeConverter.objectToFloat(value);
+ }
+
+ /**
+ * Sets the value portion of the Temperature class
+ *
+ * @param value
+ * Temperature Value in TemperatureUnit specified unit. Range depends on OEM and is not checked by SDL.
+ */
+ public void setValue(Float value) {
+ setValue(KEY_VALUE, value);
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/VideoStreamingFormat.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/VideoStreamingFormat.java
index 274c076c5..8f88b3ea8 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/VideoStreamingFormat.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/VideoStreamingFormat.java
@@ -17,6 +17,11 @@ public class VideoStreamingFormat extends RPCStruct {
public VideoStreamingFormat(){}
public VideoStreamingFormat(Hashtable<String, Object> hash){super(hash);}
+ public VideoStreamingFormat(VideoStreamingCodec codec,VideoStreamingProtocol protocol){
+ setCodec(codec);
+ setProtocol(protocol);
+ }
+
public void setProtocol(VideoStreamingProtocol protocol){
setValue(KEY_PROTOCOL, protocol);
}
@@ -32,4 +37,10 @@ public class VideoStreamingFormat extends RPCStruct {
public VideoStreamingCodec getCodec(){
return (VideoStreamingCodec) getObject(VideoStreamingCodec.class, KEY_CODEC);
}
+
+ @Override
+ public String toString() {
+ return "codec=" + String.valueOf(getCodec()) +
+ ", protocol=" + String.valueOf(getProtocol());
+ }
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/AppHMIType.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/AppHMIType.java
index 2a12bec1e..0a4f56255 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/AppHMIType.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/AppHMIType.java
@@ -45,7 +45,12 @@ public enum AppHMIType {
/**
* System App
*/
- SYSTEM;
+ SYSTEM,
+ /**
+ * Remote Control
+ */
+ REMOTE_CONTROL,
+ ;
/**
* Convert String to AppHMIType
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ButtonName.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ButtonName.java
index 1391a9d44..f478a78ee 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ButtonName.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ButtonName.java
@@ -115,7 +115,28 @@ public enum ButtonName{
*
* @since SmartDeviceLink 1.0
*/
- PRESET_9, CUSTOM_BUTTON, SEARCH;
+ PRESET_9,
+ CUSTOM_BUTTON,
+ SEARCH,
+ AC_MAX,
+ AC,
+ RECIRCULATE,
+ FAN_UP,
+ FAN_DOWN,
+ TEMP_UP,
+ TEMP_DOWN,
+ DEFROST_MAX,
+ DEFROST,
+ DEFROST_REAR,
+ UPPER_VENT,
+ LOWER_VENT,
+ VOLUME_UP,
+ VOLUME_DOWN,
+ EJECT,
+ SOURCE,
+ SHUFFLE,
+ REPEAT,
+ ;
public static ButtonName valueForString(String value) {
try{
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/DefrostZone.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/DefrostZone.java
new file mode 100644
index 000000000..4c6b15e85
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/DefrostZone.java
@@ -0,0 +1,17 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+public enum DefrostZone {
+ FRONT,
+ REAR,
+ ALL,
+ NONE,
+ ;
+
+ public static DefrostZone valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ModuleType.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ModuleType.java
new file mode 100644
index 000000000..faef92d36
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/ModuleType.java
@@ -0,0 +1,15 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+public enum ModuleType {
+ CLIMATE,
+ RADIO,
+ ;
+
+ public static ModuleType valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioBand.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioBand.java
new file mode 100644
index 000000000..2b2c862d8
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioBand.java
@@ -0,0 +1,16 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+public enum RadioBand {
+ AM,
+ FM,
+ XM,
+ ;
+
+ public static RadioBand valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioState.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioState.java
new file mode 100644
index 000000000..533c86dca
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/RadioState.java
@@ -0,0 +1,20 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+/**
+ * List possible states of a remote control radio module.
+ */
+public enum RadioState {
+ ACQUIRING,
+ ACQUIRED,
+ MULTICAST,
+ NOT_FOUND,
+ ;
+
+ public static RadioState valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/Result.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/Result.java
index 870e4115e..c0a15f235 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/Result.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/Result.java
@@ -168,7 +168,16 @@ public enum Result {
/**
* The provided hash ID does not match the hash of the current set of registered data or the core could not resume the previous data.
*/
- RESUME_FAILED;
+ RESUME_FAILED,
+ /**
+ * The requested data is not available on this vehicle or is not published for the connected app.
+ */
+ DATA_NOT_AVAILABLE,
+ /**
+ * The requested data is read only thus cannot be change via remote control
+ */
+ READ_ONLY,
+ ;
/**
* Convert String to Result
* @param value String
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/TemperatureUnit.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/TemperatureUnit.java
new file mode 100644
index 000000000..6c9b04875
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/TemperatureUnit.java
@@ -0,0 +1,14 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+public enum TemperatureUnit {
+ CELSIUS,
+ FAHRENHEIT;
+
+ public static TemperatureUnit valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/VentilationMode.java b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/VentilationMode.java
new file mode 100644
index 000000000..b7a2ae9a2
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/proxy/rpc/enums/VentilationMode.java
@@ -0,0 +1,17 @@
+package com.smartdevicelink.proxy.rpc.enums;
+
+public enum VentilationMode {
+ UPPER,
+ LOWER,
+ BOTH,
+ NONE,
+ ;
+
+ public static VentilationMode valueForString(String value) {
+ try{
+ return valueOf(value);
+ }catch(Exception e){
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingCodec.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingCodec.java
new file mode 100644
index 000000000..8e8cb3857
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingCodec.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.streaming;
+
+/**
+ * Enum for each type of audio streaming codec.
+ */
+public enum AudioStreamingCodec {
+ /**
+ * Linear-PCM without any compression.
+ */
+ LPCM;
+
+ public static AudioStreamingCodec valueForString(String value) {
+ try {
+ return valueOf(value);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingLPCMParams.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingLPCMParams.java
new file mode 100644
index 000000000..551a1f032
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingLPCMParams.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.streaming;
+
+/**
+ * A struct to hold LPCM specific audio format information.
+ */
+public class AudioStreamingLPCMParams extends AudioStreamingParams {
+ /**
+ * Sample format of linear PCM data.
+ */
+ public enum SampleFormat {
+ /**
+ * LPCM data is represented by 8-bit unsigned integers. Centerpoint is 128.
+ */
+ LPCM_8BIT_UNSIGNED,
+
+ /**
+ * LPCM data is represented by 16-bit signed integers, in little endian.
+ */
+ LPCM_16BIT_SIGNED_LITTLE_ENDIAN,
+ }
+
+ /**
+ * Sample format in which app will provide LPCM data to
+ * IAudioStreamListener.sendAudio()
+ * <p>
+ * This is reserved for future and not used right now.
+ */
+ public SampleFormat sampleFormat;
+
+ public AudioStreamingLPCMParams(SampleFormat sampleFormat, int samplingRate, int channels) {
+ super(samplingRate, channels);
+ this.sampleFormat = sampleFormat;
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingParams.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingParams.java
new file mode 100644
index 000000000..cd95ed95a
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/AudioStreamingParams.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.streaming;
+
+/**
+ * A struct to hold audio format information that are common to codecs.
+ */
+public class AudioStreamingParams {
+ /**
+ * Sampling rate in Hz, e.g. 44100
+ * <p>
+ * This is reserved for future and not used right now.
+ */
+ public int samplingRate;
+
+ /**
+ * Number of channels in the audio stream
+ * <p>
+ * This is reserved for future and not used right now.
+ */
+ public int channels;
+
+ public AudioStreamingParams(int samplingRate, int channels) {
+ this.samplingRate = samplingRate;
+ this.channels = channels;
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/RTPH264Packetizer.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/RTPH264Packetizer.java
new file mode 100644
index 000000000..2a7646579
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/RTPH264Packetizer.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2017, Xevo 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 copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.smartdevicelink.streaming;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Random;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import com.smartdevicelink.SdlConnection.SdlConnection;
+import com.smartdevicelink.SdlConnection.SdlSession;
+import com.smartdevicelink.protocol.ProtocolMessage;
+import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingCodec;
+import com.smartdevicelink.proxy.rpc.enums.VideoStreamingProtocol;
+
+/*
+ * Note for testing.
+ * The RTP stream generated by this packetizer can be tested with GStreamer (1.4 or later).
+ * Assuming that "VideoStreamPort" is configured as 5050 in smartDeviceLink.ini, here is the
+ * GStreamer pipeline that receives the stream, decode it and render it:
+ *
+ * $ gst-launch-1.0 souphttpsrc location=http://127.0.0.1:5050 ! "application/x-rtp-stream" ! rtpstreamdepay ! "application/x-rtp,media=(string)video,clock-rate=90000,encoding-name=(string)H264" ! rtph264depay ! "video/x-h264, stream-format=(string)avc, alignment=(string)au" ! avdec_h264 ! autovideosink sync=false
+ */
+
+/**
+ * This class receives H.264 byte stream (in Annex-B format), parses it, construct RTP packets
+ * from it based on RFC 6184, then frame the packets based on RFC 4571.
+ * The primary purpose of using RTP is to carry timestamp information along with the data.
+ *
+ * @author Sho Amano
+ */
+public class RTPH264Packetizer extends AbstractPacketizer implements IVideoStreamListener, Runnable {
+
+ // Approximate size of data that mOutputQueue can hold in bytes.
+ // By adding a buffer, we accept underlying transport being stuck for a short time. By setting
+ // a limit of the buffer size, we avoid buffer overflows when underlying transport is too slow.
+ private static final int MAX_QUEUE_SIZE = 256 * 1024;
+
+ private static final int FRAME_LENGTH_LEN = 2;
+ private static final int MAX_RTP_PACKET_SIZE = 65535; // because length field is two bytes (RFC 4571)
+ private static final int RTP_HEADER_LEN = 12;
+ private static final byte DEFAULT_RTP_PAYLOAD_TYPE = 96;
+ private static final int FU_INDICATOR_LEN = 1;
+ private static final int FU_HEADER_LEN = 1;
+ private static final byte TYPE_FU_A = 28;
+
+ // To align with StreamPacketizer class
+ private final static int TLS_MAX_RECORD_SIZE = 16384;
+ private final static int TLS_RECORD_HEADER_SIZE = 5;
+ private final static int TLS_RECORD_MES_AUTH_CDE_SIZE = 32;
+ private final static int TLS_MAX_RECORD_PADDING_SIZE = 256;
+
+ private final static int MAX_DATA_SIZE_FOR_ENCRYPTED_SERVICE =
+ TLS_MAX_RECORD_SIZE - TLS_RECORD_HEADER_SIZE - TLS_RECORD_MES_AUTH_CDE_SIZE- TLS_MAX_RECORD_PADDING_SIZE;
+
+ private boolean mServiceProtected;
+ private Thread mThread;
+ private BlockingQueue<ByteBuffer> mOutputQueue;
+ private volatile boolean mPaused;
+ private boolean mWaitForIDR;
+ private NALUnitReader mNALUnitReader;
+ private byte mPayloadType = 0;
+ private int mSSRC = 0;
+ private char mSequenceNum = 0;
+ private int mInitialPTS = 0;
+
+ /**
+ * Constructor
+ *
+ * @param streamListener The listener which this packetizer outputs SDL frames to
+ * @param serviceType The value of "Service Type" field in SDL frames
+ * @param sessionID The value of "Session ID" field in SDL frames
+ * @param session The SdlSession instance that this packetizer belongs to
+ */
+ public RTPH264Packetizer(IStreamListener streamListener,
+ SessionType serviceType, byte sessionID, SdlSession session) throws IOException {
+
+ super(streamListener, null, serviceType, sessionID, session);
+
+ mServiceProtected = session.isServiceProtected(_serviceType);
+
+ bufferSize = (int)this._session.getMtu(SessionType.NAV);
+ if (bufferSize == 0) {
+ // fail safe
+ bufferSize = MAX_DATA_SIZE_FOR_ENCRYPTED_SERVICE;
+ }
+ if (mServiceProtected && bufferSize > MAX_DATA_SIZE_FOR_ENCRYPTED_SERVICE) {
+ bufferSize = MAX_DATA_SIZE_FOR_ENCRYPTED_SERVICE;
+ }
+
+ mOutputQueue = new LinkedBlockingQueue<ByteBuffer>(MAX_QUEUE_SIZE / bufferSize);
+ mNALUnitReader = new NALUnitReader();
+ mPayloadType = DEFAULT_RTP_PAYLOAD_TYPE;
+
+ Random r = new Random();
+ mSSRC = r.nextInt();
+
+ // initial value of the sequence number and timestamp should be random ([5.1] in RFC3550)
+ mSequenceNum = (char)r.nextInt(65536);
+ mInitialPTS = r.nextInt();
+ }
+
+ /**
+ * Sets the Payload Type (PT) of RTP header field.
+ *
+ * Use this method if PT needs to be specified. The value should be between 0 and 127.
+ * Otherwise, a default value (96) is used.
+ *
+ * @param type A value indicating the Payload Type
+ */
+ public void setPayloadType(byte type) {
+ if (type >= 0 && type <= 127) {
+ mPayloadType = type;
+ } else {
+ mPayloadType = DEFAULT_RTP_PAYLOAD_TYPE;
+ }
+ }
+
+ /**
+ * Sets the SSRC of RTP header field.
+ *
+ * Use this method if SSRC needs to be specified. Otherwise, a random value is generated and
+ * used.
+ *
+ * @param ssrc An integer value representing SSRC
+ */
+ public void setSSRC(int ssrc) {
+ mSSRC = ssrc;
+ }
+
+ /**
+ * Starts this packetizer.
+ *
+ * It is recommended that the video encoder is started after the packetizer is started.
+ */
+ @Override
+ public void start() throws IOException {
+ if (mThread != null) {
+ return;
+ }
+
+ mThread = new Thread(this);
+ mThread.start();
+ }
+
+ /**
+ * Stops this packetizer.
+ *
+ * It is recommended that the video encoder is stopped prior to the packetizer.
+ */
+ @Override
+ public void stop() {
+ if (mThread == null) {
+ return;
+ }
+
+ mThread.interrupt();
+ mThread = null;
+
+ mPaused = false;
+ mWaitForIDR = false;
+ mOutputQueue.clear();
+ }
+
+ /**
+ * Pauses this packetizer.
+ *
+ * This pauses the packetizer but does not pause the video encoder.
+ */
+ @Override
+ public void pause() {
+ mPaused = true;
+ }
+
+ /**
+ * Resumes this packetizer.
+ */
+ @Override
+ public void resume() {
+ mWaitForIDR = true;
+ mPaused = false;
+ }
+
+ /**
+ * The thread routine.
+ */
+ public void run() {
+ SdlConnection connection = _session.getSdlConnection();
+
+ while (mThread != null && !mThread.isInterrupted()) {
+ ByteBuffer frame;
+ try {
+ frame = mOutputQueue.take();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+
+ while (frame.hasRemaining()) {
+ int len = frame.remaining() > bufferSize ? bufferSize : frame.remaining();
+
+ ProtocolMessage pm = new ProtocolMessage();
+ pm.setSessionID(_rpcSessionID);
+ pm.setSessionType(_serviceType);
+ pm.setFunctionID(0);
+ pm.setCorrID(0);
+ pm.setData(frame.array(), frame.arrayOffset() + frame.position(), len);
+ pm.setPayloadProtected(mServiceProtected);
+
+ _streamListener.sendStreamPacket(pm);
+
+ frame.position(frame.position() + len);
+ }
+ }
+
+ // XXX: This is added to sync with StreamPacketizer. Actually it shouldn't be here since
+ // it's confusing that a packetizer takes care of End Service request.
+ if (connection != null) {
+ connection.endService(_serviceType, _rpcSessionID);
+ }
+ }
+
+ /**
+ * Called by the app and encoder.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IVideoStreamListener#sendFrame(byte[], int, int, long)
+ */
+ @Override
+ public void sendFrame(byte[] data, int offset, int length, long presentationTimeUs)
+ throws ArrayIndexOutOfBoundsException {
+ mNALUnitReader.init(data, offset, length);
+ onEncoderOutput(mNALUnitReader, presentationTimeUs);
+ }
+
+ /**
+ * Called by the app and encoder.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IVideoStreamListener#sendFrame(ByteBuffer, long)
+ */
+ @Override
+ public void sendFrame(ByteBuffer data, long presentationTimeUs) {
+ mNALUnitReader.init(data);
+ onEncoderOutput(mNALUnitReader, presentationTimeUs);
+ }
+
+ private void onEncoderOutput(NALUnitReader nalUnitReader, long ptsInUs) {
+ if (mPaused) {
+ return;
+ }
+
+ ByteBuffer nalUnit;
+
+ while ((nalUnit = nalUnitReader.getNalUnit()) != null) {
+ if (mWaitForIDR) {
+ if (isIDR(nalUnit)) {
+ mWaitForIDR = false;
+ } else {
+ continue;
+ }
+ }
+ outputRTPFrames(nalUnit, ptsInUs, nalUnitReader.hasConsumedAll());
+ }
+ }
+
+ private boolean outputRTPFrames(ByteBuffer nalUnit, long ptsInUs, boolean isLast) {
+ if (RTP_HEADER_LEN + nalUnit.remaining() > MAX_RTP_PACKET_SIZE) {
+ // Split into multiple Fragmentation Units ([5.8] in RFC 6184)
+ byte firstByte = nalUnit.get();
+ boolean firstFragment = true;
+ boolean lastFragment = false;
+
+ while (nalUnit.remaining() > 0) {
+ int payloadLength = MAX_RTP_PACKET_SIZE - (RTP_HEADER_LEN + FU_INDICATOR_LEN + FU_HEADER_LEN);
+ if (nalUnit.remaining() <= payloadLength) {
+ payloadLength = nalUnit.remaining();
+ lastFragment = true;
+ }
+
+ ByteBuffer frame = allocateRTPFrame(FU_INDICATOR_LEN + FU_HEADER_LEN + payloadLength,
+ false, isLast, ptsInUs);
+ // FU indicator
+ frame.put((byte)((firstByte & 0xE0) | TYPE_FU_A));
+ // FU header
+ frame.put((byte)((firstFragment ? 0x80 : lastFragment ? 0x40 : 0) | (firstByte & 0x1F)));
+ // FU payload
+ frame.put(nalUnit.array(), nalUnit.position(), payloadLength);
+ nalUnit.position(nalUnit.position() + payloadLength);
+ frame.flip();
+
+ try {
+ mOutputQueue.put(frame);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+
+ firstFragment = false;
+ }
+ } else {
+ // Use Single NAL Unit Packet ([5.6] in RFC 6184)
+ ByteBuffer frame = allocateRTPFrame(nalUnit.remaining(), false, isLast, ptsInUs);
+ frame.put(nalUnit);
+ frame.flip();
+
+ try {
+ mOutputQueue.put(frame);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private ByteBuffer allocateRTPFrame(int rtpPayloadLen,
+ boolean hasPadding, boolean isLast, long ptsInUs) {
+ if (rtpPayloadLen <= 0) {
+ throw new IllegalArgumentException("Invalid rtpPayloadLen value: " + rtpPayloadLen);
+ }
+ if (ptsInUs < 0) {
+ throw new IllegalArgumentException("Invalid ptsInUs value: " + ptsInUs);
+ }
+
+ int packetLength = RTP_HEADER_LEN + rtpPayloadLen;
+ if (packetLength > MAX_RTP_PACKET_SIZE) {
+ throw new IllegalArgumentException("Invalid rtpPayloadLen value: " + rtpPayloadLen);
+ }
+ int ptsIn90kHz = (int)(ptsInUs * 9 / 100) + mInitialPTS;
+
+ ByteBuffer frame = ByteBuffer.allocate(FRAME_LENGTH_LEN + packetLength);
+ frame.order(ByteOrder.BIG_ENDIAN);
+ frame.putShort((short)packetLength);
+
+ // Version = 2, Padding = hasPadding, Extension = 0, CSRC count = 0
+ frame.put((byte)(0x80 | (hasPadding ? 0x20 : 0)))
+ // Marker = isLast, Payload type = mPayloadType
+ .put((byte)((isLast ? 0x80 : 0) | (mPayloadType & 0x7F)))
+ .putChar(mSequenceNum)
+ .putInt(ptsIn90kHz)
+ .putInt(mSSRC);
+
+ if (frame.position() != FRAME_LENGTH_LEN + RTP_HEADER_LEN) {
+ throw new RuntimeException("Data size in ByteBuffer mismatch");
+ }
+
+ mSequenceNum++;
+ return frame;
+ }
+
+ private static boolean isIDR(ByteBuffer nalUnit) {
+ if (nalUnit == null || !nalUnit.hasRemaining()) {
+ throw new IllegalArgumentException("Invalid nalUnit arg");
+ }
+
+ byte nalUnitType = (byte)(nalUnit.get(nalUnit.position()) & 0x1F);
+ return nalUnitType == 5;
+ }
+
+
+ private static int SKIP_TABLE[] = new int[256];
+ static {
+ // Sunday's quick search algorithm is used to find the start code.
+ // Prepare the table (SKIP_TABLE[0] = 2, SKIP_TABLE[1] = 1 and other elements will be 4).
+ byte[] NAL_UNIT_START_CODE = {0, 0, 1};
+ int searchStringLen = NAL_UNIT_START_CODE.length;
+ for (int i = 0; i < SKIP_TABLE.length; i++) {
+ SKIP_TABLE[i] = searchStringLen + 1;
+ }
+ for (int i = 0; i < searchStringLen; i++) {
+ SKIP_TABLE[NAL_UNIT_START_CODE[i] & 0xFF] = searchStringLen - i;
+ }
+ }
+
+ private class NALUnitReader {
+ private byte[] mData;
+ private int mOffset;
+ private int mLimit;
+
+ NALUnitReader() {
+ }
+
+ void init(byte[] data) {
+ mData = data;
+ mOffset = 0;
+ mLimit = data.length;
+ }
+
+ void init(byte[] data, int offset, int length) throws ArrayIndexOutOfBoundsException {
+ if (offset < 0 || offset > data.length || length <= 0 || offset + length > data.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ mData = data;
+ mOffset = offset;
+ mLimit = offset + length;
+ }
+
+ void init(ByteBuffer data) {
+ if (data == null || data.remaining() == 0) {
+ mData = null;
+ mOffset = 0;
+ mLimit = 0;
+ return;
+ }
+
+ if (data.hasArray()) {
+ mData = data.array();
+ mOffset = data.position() + data.arrayOffset();
+ mLimit = mOffset + data.remaining();
+
+ // mark the buffer as consumed
+ data.position(data.position() + data.remaining());
+ } else {
+ byte[] buffer = new byte[data.remaining()];
+ data.get(buffer);
+
+ mData = buffer;
+ mOffset = 0;
+ mLimit = buffer.length;
+ }
+ }
+
+ ByteBuffer getNalUnit() {
+ if (hasConsumedAll()) {
+ return null;
+ }
+
+ int pos = mOffset;
+ int start = -1;
+
+ while (mLimit - pos >= 3) {
+ if (mData[pos] == 0 && mData[pos+1] == 0 && mData[pos+2] == 1) {
+ if (start != -1) {
+ // We've found a start code, a NAL unit and then another start code.
+ mOffset = pos;
+ // remove 0x00s in front of the start code
+ while (pos > start && mData[pos-1] == 0) {
+ pos--;
+ }
+ if (pos > start) {
+ return ByteBuffer.wrap(mData, start, pos - start);
+ } else {
+ // No NAL unit between two start codes?! Forget it and search for
+ // another start code.
+ pos = mOffset;
+ }
+ }
+ // This is the first start code.
+ pos += 3;
+ start = pos;
+ } else {
+ try {
+ pos += SKIP_TABLE[mData[pos+3] & 0xFF];
+ } catch (ArrayIndexOutOfBoundsException e) {
+ break;
+ }
+ }
+ }
+
+ mOffset = mLimit;
+ if (start != -1 && mLimit > start) {
+ // We've found a start code and then reached to the end of array.
+ return ByteBuffer.wrap(mData, start, mLimit - start);
+ }
+ // A start code was not found
+ return null;
+ }
+
+ boolean hasConsumedAll() {
+ return (mData == null) || (mLimit - mOffset < 4);
+ }
+ }
+}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java
index 40cc7d5ed..f6a668279 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java
@@ -2,13 +2,18 @@ package com.smartdevicelink.streaming;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import com.smartdevicelink.SdlConnection.SdlConnection;
import com.smartdevicelink.SdlConnection.SdlSession;
import com.smartdevicelink.protocol.ProtocolMessage;
import com.smartdevicelink.protocol.enums.SessionType;
+import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
+import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
-public class StreamPacketizer extends AbstractPacketizer implements Runnable{
+public class StreamPacketizer extends AbstractPacketizer implements IVideoStreamListener, IAudioStreamListener, Runnable{
public final static String TAG = "StreamPacketizer";
@@ -23,21 +28,31 @@ public class StreamPacketizer extends AbstractPacketizer implements Runnable{
private final static int BUFF_READ_SIZE = TLS_MAX_RECORD_SIZE - TLS_RECORD_HEADER_SIZE - TLS_RECORD_MES_AUTH_CDE_SIZE - TLS_MAX_RECORD_PADDING_SIZE;
+ // Approximate size of data that mOutputQueue can hold in bytes.
+ // By adding a buffer, we accept underlying transport being stuck for a short time. By setting
+ // a limit of the buffer size, we avoid buffer overflows when underlying transport is too slow.
+ private static final int MAX_QUEUE_SIZE = 256 * 1024;
+
public SdlConnection sdlConnection = null;
private Object mPauseLock;
private boolean mPaused;
private boolean isServiceProtected = false;
-
+ private BlockingQueue<ByteBuffer> mOutputQueue;
+
public StreamPacketizer(IStreamListener streamListener, InputStream is, SessionType sType, byte rpcSessionID, SdlSession session) throws IOException {
super(streamListener, is, sType, rpcSessionID, session);
mPauseLock = new Object();
mPaused = false;
isServiceProtected = _session.isServiceProtected(_serviceType);
+ if (bufferSize == 0) {
+ // fail safe
+ bufferSize = BUFF_READ_SIZE;
+ }
if(isServiceProtected){ //If our service is encrypted we can only use 1024 as the max buffer size.
bufferSize = BUFF_READ_SIZE;
buffer = new byte[bufferSize];
}
-
+ mOutputQueue = new LinkedBlockingQueue<ByteBuffer>(MAX_QUEUE_SIZE / bufferSize);
}
public void start() throws IOException {
@@ -75,20 +90,48 @@ public class StreamPacketizer extends AbstractPacketizer implements Runnable{
}
}
- length = is.read(buffer, 0, bufferSize);
-
- if (length >= 0)
- {
- ProtocolMessage pm = new ProtocolMessage();
- pm.setSessionID(_rpcSessionID);
- pm.setSessionType(_serviceType);
- pm.setFunctionID(0);
- pm.setCorrID(0);
- pm.setData(buffer, length);
- pm.setPayloadProtected(isServiceProtected);
-
- if (t != null && !t.isInterrupted())
- _streamListener.sendStreamPacket(pm);
+ if (is != null) { // using InputStream interface
+ length = is.read(buffer, 0, bufferSize);
+
+ if (length >= 0) {
+ ProtocolMessage pm = new ProtocolMessage();
+ pm.setSessionID(_rpcSessionID);
+ pm.setSessionType(_serviceType);
+ pm.setFunctionID(0);
+ pm.setCorrID(0);
+ pm.setData(buffer, length);
+ pm.setPayloadProtected(isServiceProtected);
+
+ if (t != null && !t.isInterrupted()) {
+ _streamListener.sendStreamPacket(pm);
+ }
+ }
+ } else { // using sendFrame interface
+ ByteBuffer frame;
+ try {
+ frame = mOutputQueue.take();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+
+ while (frame.hasRemaining()) {
+ int len = frame.remaining() > bufferSize ? bufferSize : frame.remaining();
+
+ ProtocolMessage pm = new ProtocolMessage();
+ pm.setSessionID(_rpcSessionID);
+ pm.setSessionType(_serviceType);
+ pm.setFunctionID(0);
+ pm.setCorrID(0);
+ pm.setData(frame.array(), frame.arrayOffset() + frame.position(), len);
+ pm.setPayloadProtected(isServiceProtected);
+
+ if (t != null && !t.isInterrupted()) {
+ _streamListener.sendStreamPacket(pm);
+ }
+
+ frame.position(frame.position() + len);
+ }
}
}
} catch (IOException e)
@@ -119,4 +162,82 @@ public class StreamPacketizer extends AbstractPacketizer implements Runnable{
mPauseLock.notifyAll();
}
}
+
+ /**
+ * Called by the app.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IVideoStreamListener#sendFrame(byte[], int, int, long)
+ */
+ @Override
+ public void sendFrame(byte[] data, int offset, int length, long presentationTimeUs)
+ throws ArrayIndexOutOfBoundsException {
+ sendArrayData(data, offset, length);
+ }
+
+ /**
+ * Called by the app.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IVideoStreamListener#sendFrame(ByteBuffer, long)
+ */
+ @Override
+ public void sendFrame(ByteBuffer data, long presentationTimeUs) {
+ sendByteBufferData(data);
+ }
+
+ /**
+ * Called by the app.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IAudioStreamListener#sendAudio(byte[], int, int, long)
+ */
+ @Override
+ public void sendAudio(byte[] data, int offset, int length, long presentationTimeUs)
+ throws ArrayIndexOutOfBoundsException {
+ sendArrayData(data, offset, length);
+ }
+
+ /**
+ * Called by the app.
+ *
+ * @see com.smartdevicelink.proxy.interfaces.IAudioStreamListener#sendAudio(ByteBuffer, long)
+ */
+ @Override
+ public void sendAudio(ByteBuffer data, long presentationTimeUs) {
+ sendByteBufferData(data);
+ }
+
+ private void sendArrayData(byte[] data, int offset, int length)
+ throws ArrayIndexOutOfBoundsException {
+ if (offset < 0 || offset > data.length || length <= 0 || offset + length > data.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ // StreamPacketizer does not need to split a video frame into NAL units
+ ByteBuffer buffer = ByteBuffer.allocate(length);
+ buffer.put(data, offset, length);
+ buffer.flip();
+
+ try {
+ mOutputQueue.put(buffer);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private void sendByteBufferData(ByteBuffer data) {
+ if (data == null || data.remaining() == 0) {
+ return;
+ }
+
+ // copy the whole buffer, so that even if the app modifies original ByteBuffer after
+ // sendFrame() or sendAudio() call, our buffer will stay intact
+ ByteBuffer buffer = ByteBuffer.allocate(data.remaining());
+ buffer.put(data);
+ buffer.flip();
+
+ try {
+ mOutputQueue.put(buffer);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/streaming/VideoStreamingParameters.java b/sdl_android/src/main/java/com/smartdevicelink/streaming/VideoStreamingParameters.java
index c8c17d8bc..cac4ebbb8 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/streaming/VideoStreamingParameters.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/streaming/VideoStreamingParameters.java
@@ -96,4 +96,10 @@ public class VideoStreamingParameters {
public ImageResolution getResolution() {
return resolution;
}
+
+ @Override
+ public String toString() {
+ return "format: {" + String.valueOf(format) +
+ "}, resolution: {" + String.valueOf(resolution) + "}";
+ }
} \ No newline at end of file
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java b/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
index 66e415f29..92dce9dbe 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.os.Build;
import android.util.Log;
import com.smartdevicelink.util.HttpRequestTask;
@@ -117,7 +118,7 @@ public class RouterServiceValidator {
if(this.service != null){
Log.d(TAG, "Supplied service name of " + this.service.getClassName());
- if(!isServiceRunning(context,this.service)){
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !isServiceRunning(context,this.service)){
//This means our service isn't actually running, so set to null. Hopefully we can find a real router service after this.
service = null;
Log.w(TAG, "Supplied service is not actually running.");
@@ -129,11 +130,17 @@ public class RouterServiceValidator {
}
}
if(this.service == null){
- this.service= componentNameForServiceRunning(pm); //Change this to an array if multiple services are started?
- if(this.service == null){ //if this is still null we know there is no service running so we can return false
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O ) {
+ this.service = componentNameForServiceRunning(pm); //Change this to an array if multiple services are started?
+ if (this.service == null) { //if this is still null we know there is no service running so we can return false
+ wakeUpRouterServices();
+ return false;
+ }
+ }else{
wakeUpRouterServices();
return false;
}
+
}
//Log.d(TAG, "Checking app package: " + service.getClassName());
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
index cfcd486b2..94bb3c51e 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java
@@ -1,22 +1,39 @@
package com.smartdevicelink.transport;
-import java.util.List;
-import java.util.Locale;
-import java.util.Vector;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import com.smartdevicelink.util.AndroidTools;
-import com.smartdevicelink.transport.RouterServiceValidator.TrustedListCallback;
-
+import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Build;
import android.util.Log;
+import com.smartdevicelink.transport.RouterServiceValidator.TrustedListCallback;
+import com.smartdevicelink.util.AndroidTools;
+import com.smartdevicelink.util.ServiceFinder;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import static com.smartdevicelink.transport.TransportConstants.BIND_LOCATION_CLASS_NAME_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.BIND_LOCATION_PACKAGE_NAME_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.FOREGROUND_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME;
+
public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
private static final String TAG = "Sdl Broadcast Receiver";
@@ -74,8 +91,10 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
return;
}
- boolean didStart = false;
- localRouterClass = defineLocalSdlRouterClass();
+ boolean didStart = false;
+ if (localRouterClass == null){
+ localRouterClass = defineLocalSdlRouterClass();
+ }
//This will only be true if we are being told to reopen our SDL service because SDL is enabled
if(action.equalsIgnoreCase(TransportConstants.START_ROUTER_SERVICE_ACTION)){
@@ -127,10 +146,10 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
return;
}
}
-
+ Log.d(TAG, "Check for local router");
if(localRouterClass!=null){ //If there is a supplied router service lets run some logic regarding starting one
- if(!didStart){
+ if(!didStart){Log.d(TAG, "attempting to wake up router service");
didStart = wakeUpRouterService(context, true,false);
}
@@ -145,42 +164,109 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
context.sendBroadcast(restart);
}
}
-
- private boolean wakeUpRouterService(Context context, boolean ping, boolean altTransportWake){
- if(!isRouterServiceRunning(context, ping)){
- //If there isn't a service running we should try to start one
- //The under class should have implemented this....
-
- //So let's start up our service since no copy is running
- Intent serviceIntent = new Intent(context, localRouterClass);
- if(altTransportWake){
- serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
- }
- try {
- context.startService(serviceIntent);
- }catch (SecurityException e){
- Log.e(TAG, "Security exception, process is bad");
- return false; // Let's exit, we can't start the service
- }
- return true;
- }else{
- if(altTransportWake && runningBluetoothServicePackage!=null && runningBluetoothServicePackage.size()>0){
- Intent serviceIntent = new Intent();
- serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
- //context.startService(serviceIntent);
- for(ComponentName compName: runningBluetoothServicePackage){
- serviceIntent.setComponent(compName);
- context.startService(serviceIntent);
- }
- return true;
- }
- return false;
- }
+ @TargetApi(Build.VERSION_CODES.O)
+ private boolean wakeUpRouterService(final Context context, final boolean ping, final boolean altTransportWake){
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ if (!isRouterServiceRunning(context, ping)) {
+ //If there isn't a service running we should try to start one
+ //The under class should have implemented this....
+ Log.d(TAG, "No router service running, starting ours");
+ //So let's start up our service since no copy is running
+ Intent serviceIntent = new Intent(context, localRouterClass);
+ if (altTransportWake) {
+ serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
+ }
+ try {
+ context.startService(serviceIntent);
+ } catch (SecurityException e) {
+ Log.e(TAG, "Security exception, process is bad");
+ return false; // Let's exit, we can't start the service
+ }
+ return true;
+ } else {
+ if (altTransportWake && runningBluetoothServicePackage != null && runningBluetoothServicePackage.size() > 0) {
+ wakeRouterServiceAltTransport(context);
+ return true;
+ }
+ return false;
+ }
+ }else{ //We are android Oreo or newer
+ ServiceFinder finder = new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() {
+ @Override
+ public void onComplete(Vector<ComponentName> routerServices) {
+ runningBluetoothServicePackage = new Vector<ComponentName>();
+ runningBluetoothServicePackage.addAll(routerServices);
+ if (runningBluetoothServicePackage.isEmpty()) {
+ //If there isn't a service running we should try to start one
+ //We will try to sort the SDL enabled apps and find the one that's been installed the longest
+ Intent serviceIntent;
+ final PackageManager packageManager = context.getPackageManager();
+ Vector<ResolveInfo> apps = new Vector(AndroidTools.getSdlEnabledApps(context, "").values()); //we want our package
+ if (apps != null && !apps.isEmpty()) {
+ Collections.sort(apps, new Comparator<ResolveInfo>() {
+ @Override
+ public int compare(ResolveInfo resolveInfo, ResolveInfo t1) {
+ try {
+ PackageInfo thisPack = packageManager.getPackageInfo(resolveInfo.activityInfo.packageName, 0);
+ PackageInfo itPack = packageManager.getPackageInfo(t1.activityInfo.packageName, 0);
+ if (thisPack.lastUpdateTime < itPack.lastUpdateTime) {
+ return -1;
+ } else if (thisPack.lastUpdateTime > itPack.lastUpdateTime) {
+ return 1;
+ }
+
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+ });
+ String packageName = apps.get(0).activityInfo.packageName;
+ serviceIntent = new Intent();
+ serviceIntent.setComponent(new ComponentName(packageName, packageName +".SdlRouterService"));
+ } else{
+ Log.d(TAG, "No router service running, starting ours");
+ //So let's start up our service since no copy is running
+ serviceIntent = new Intent(context, localRouterClass);
+
+ }
+ if (altTransportWake) {
+ serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
+ }
+ try {
+ serviceIntent.putExtra(FOREGROUND_EXTRA, true);
+ context.startForegroundService(serviceIntent);
+
+ } catch (SecurityException e) {
+ Log.e(TAG, "Security exception, process is bad");
+ }
+ } else {
+ if (altTransportWake && runningBluetoothServicePackage != null && runningBluetoothServicePackage.size() > 0) {
+ wakeRouterServiceAltTransport(context);
+ return;
+ }
+ return;
+ }
+ }
+ });
+ return true;
+ }
+ }
+
+ private void wakeRouterServiceAltTransport(Context context){
+ Intent serviceIntent = new Intent();
+ serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT);
+ for (ComponentName compName : runningBluetoothServicePackage) {
+ serviceIntent.setComponent(compName);
+ context.startService(serviceIntent);
+
+ }
}
/**
- * Determines if an instance of the Router Service is currently running on the device.
+ * Determines if an instance of the Router Service is currently running on the device.<p>
+ * <b>Note:</b> This method no longer works on Android Oreo or newer
* @param context A context to access Android system services through.
* @param pingService Set this to true if you want to make sure the service is up and listening to bluetooth
* @return True if a SDL Router Service is currently running, false otherwise.
@@ -190,31 +276,30 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
Log.e(TAG, "Can't look for router service, context supplied was null");
return false;
}
- ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- if(runningBluetoothServicePackage==null){
+ if (runningBluetoothServicePackage == null) {
runningBluetoothServicePackage = new Vector<ComponentName>();
- }else{
+ } else {
runningBluetoothServicePackage.clear();
}
+ ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ manager.getRunningAppProcesses();
List<RunningServiceInfo> runningServices = null;
- try{
+ try {
runningServices = manager.getRunningServices(Integer.MAX_VALUE);
- }catch(NullPointerException e){
+ } catch (NullPointerException e) {
Log.e(TAG, "Can't get list of running services");
return false;
}
- for (RunningServiceInfo service : runningServices) {
+ for (RunningServiceInfo service : runningServices) {
//We will check to see if it contains this name, should be pretty specific
- //Log.d(TAG, "Found Service: "+ service.service.getClassName());
- if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME) && AndroidTools.isServiceExported(context, service.service)) {
-
- runningBluetoothServicePackage.add(service.service); //Store which instance is running
- if(pingService){
+ //Log.d(TAG, "Found Service: "+ service.service.getClassName());
+ if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME) && AndroidTools.isServiceExported(context, service.service)) {
+ runningBluetoothServicePackage.add(service.service); //Store which instance is running
+ if (pingService) {
pingRouterService(context, service.service.getPackageName(), service.service.getClassName());
- }
- }
- }
-
+ }
+ }
+ }
return runningBluetoothServicePackage.size() > 0;
}
@@ -239,33 +324,46 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{
// This service could not be started
}
}
-
+
/**
* This call will reach out to all SDL related router services to check if they're connected. If a the router service is connected, it will react by pinging all clients. This receiver will then
* receive that ping and if the router service is trusted, the onSdlEnabled method will be called.
* @param context
*/
- public static void queryForConnectedService(Context context){
+ public static void queryForConnectedService(final Context context){
//Leverage existing call. Include ping bit
- requestTransportStatus(context,null,true);
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
+ ServiceFinder finder = new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() {
+ @Override
+ public void onComplete(Vector<ComponentName> routerServices) {
+ runningBluetoothServicePackage = new Vector<ComponentName>();
+ runningBluetoothServicePackage.addAll(routerServices);
+ requestTransportStatus(context,null,true,false);
+ }
+ });
+
+ }else{
+ requestTransportStatus(context,null,true,true);
+ }
}
/**
* If a Router Service is running, this method determines if that service is connected to a device over some form of transport.
* @param context A context to access Android system services through. If null is passed, this will always return false
* @param callback Use this callback to find out if the router service is connected or not.
*/
+ @Deprecated
public static void requestTransportStatus(Context context, final SdlRouterStatusProvider.ConnectedStatusCallback callback){
- requestTransportStatus(context,callback,false);
+ requestTransportStatus(context,callback,false, true);
}
- private static void requestTransportStatus(Context context, final SdlRouterStatusProvider.ConnectedStatusCallback callback, final boolean triggerRouterServicePing){
+ private static void requestTransportStatus(Context context, final SdlRouterStatusProvider.ConnectedStatusCallback callback, final boolean triggerRouterServicePing, final boolean lookForServices){
if(context == null){
if(callback!=null){
callback.onConnectionStatusUpdate(false, null,context);
}
return;
}
- if(isRouterServiceRunning(context,false) && !runningBluetoothServicePackage.isEmpty()){ //So there is a service up, let's see if it's connected
+ if((!lookForServices || isRouterServiceRunning(context,false)) && !runningBluetoothServicePackage.isEmpty()){ //So there is a service up, let's see if it's connected
final ConcurrentLinkedQueue<ComponentName> list = new ConcurrentLinkedQueue<ComponentName>(runningBluetoothServicePackage);
final SdlRouterStatusProvider.ConnectedStatusCallback sdlBrCallback = new SdlRouterStatusProvider.ConnectedStatusCallback() {
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
index d3a4fd051..5ca8cec0e 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java
@@ -1,6 +1,5 @@
package com.smartdevicelink.transport;
-import static com.smartdevicelink.proxy.constants.Names.info;
import static com.smartdevicelink.transport.TransportConstants.CONNECTED_DEVICE_STRING_EXTRA_NAME;
import static com.smartdevicelink.transport.TransportConstants.FORMED_PACKET_EXTRA_NAME;
import static com.smartdevicelink.transport.TransportConstants.HARDWARE_DISCONNECTED;
@@ -23,11 +22,14 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.Manifest;
+
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -72,6 +74,30 @@ import com.smartdevicelink.transport.utl.ByteAraryMessageAssembler;
import com.smartdevicelink.transport.utl.ByteArrayMessageSpliter;
import com.smartdevicelink.util.AndroidTools;
import com.smartdevicelink.util.BitConverter;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static com.smartdevicelink.transport.TransportConstants.CONNECTED_DEVICE_STRING_EXTRA_NAME;
+import static com.smartdevicelink.transport.TransportConstants.FOREGROUND_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.FORMED_PACKET_EXTRA_NAME;
+import static com.smartdevicelink.transport.TransportConstants.HARDWARE_DISCONNECTED;
+import static com.smartdevicelink.transport.TransportConstants.SDL_NOTIFICATION_CHANNEL_ID;
+import static com.smartdevicelink.transport.TransportConstants.SDL_NOTIFICATION_CHANNEL_NAME;
+import static com.smartdevicelink.transport.TransportConstants.SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME;
/**
* <b>This class should not be modified by anyone outside of the approved contributors of the SmartDeviceLink project.</b>
* This service is a central point of communication between hardware and the registered clients. It will multiplex a single transport
@@ -181,6 +207,7 @@ public class SdlRouterService extends Service{
registrationIntent.setAction(action);
registrationIntent.putExtra(TransportConstants.BIND_LOCATION_PACKAGE_NAME_EXTRA, this.getPackageName());
registrationIntent.putExtra(TransportConstants.BIND_LOCATION_CLASS_NAME_EXTRA, this.getClass().getName());
+ registrationIntent.setFlags((Intent.FLAG_RECEIVER_FOREGROUND));
return registrationIntent;
}
@@ -889,6 +916,9 @@ public class SdlRouterService extends Service{
}
}
if(intent != null ){
+ if(intent.getBooleanExtra(FOREGROUND_EXTRA, false)){
+ enterForeground();
+ }
if(intent.hasExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA)){
//Make sure we are listening on RFCOMM
if(startSequenceComplete){ //We only check if we are sure we are already through the start up process
@@ -1029,18 +1059,37 @@ public class SdlRouterService extends Service{
notification = builder.getNotification();
}else{
+ if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
+ //Now we need to add a notification channel
+ NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ String channelId = SDL_NOTIFICATION_CHANNEL_ID;
+ CharSequence channelName = SDL_NOTIFICATION_CHANNEL_NAME;
+ int importance = NotificationManager.IMPORTANCE_DEFAULT;
+ NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, importance);
+ notificationChannel.enableLights(false);
+ notificationChannel.enableVibration(false);
+ notificationManager.createNotificationChannel(notificationChannel);
+ builder.setChannelId(channelId);
+
+ }
notification = builder.build();
}
if(notification == null){
Log.e(TAG, "Notification was null");
+ return;
}
startForeground(FOREGROUND_SERVICE_ID, notification);
isForeground = true;
}
-
+
private void exitForeground(){
if(isForeground){
+ if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
+ NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.deleteNotificationChannel(TransportConstants.SDL_NOTIFICATION_CHANNEL_ID);
+ }
+
this.stopForeground(true);
}
}
@@ -1741,7 +1790,7 @@ public class SdlRouterService extends Service{
}
}
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
private boolean removeAllSessionsWithAppId(String appId){
synchronized(SESSION_LOCK){
if(sessionMap!=null){
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
index 89187d524..1d1b3b792 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java
@@ -7,6 +7,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -488,7 +489,7 @@ public class TransportBroker {
}
//Make sure we know where to bind to
if(this.routerService==null){
- if(!isRouterServiceRunning(getContext())){//We should be able to ignore this case because of the validation now
+ if((Build.VERSION.SDK_INT < Build.VERSION_CODES.O) && !isRouterServiceRunning(getContext())){//We should be able to ignore this case because of the validation now
Log.d(TAG,whereToReply + " found no router service. Shutting down.");
this.onHardwareDisconnected(null);
return false;
diff --git a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java
index 6203aa3e7..8db44f500 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/transport/TransportConstants.java
@@ -10,6 +10,7 @@ package com.smartdevicelink.transport;
*/
public class TransportConstants {
public static final String START_ROUTER_SERVICE_ACTION ="sdl.router.startservice";
+ public static final String FOREGROUND_EXTRA = "foreground";
public static final String BIND_LOCATION_PACKAGE_NAME_EXTRA = "BIND_LOCATION_PACKAGE_NAME_EXTRA";
public static final String BIND_LOCATION_CLASS_NAME_EXTRA = "BIND_LOCATION_CLASS_NAME_EXTRA";
@@ -54,6 +55,12 @@ public class TransportConstants {
public static final String PING_ROUTER_SERVICE_EXTRA = "ping.router.service";
+ public static final String SDL_NOTIFICATION_CHANNEL_ID = "sdl_notification_channel";
+ public static final String SDL_NOTIFICATION_CHANNEL_NAME = "SmartDeviceLink";
+
+
+
+
/**
* This class houses all important router service versions
*/
diff --git a/sdl_android/src/main/java/com/smartdevicelink/util/AndroidTools.java b/sdl_android/src/main/java/com/smartdevicelink/util/AndroidTools.java
index ff8819ec3..bc55dcb07 100644
--- a/sdl_android/src/main/java/com/smartdevicelink/util/AndroidTools.java
+++ b/sdl_android/src/main/java/com/smartdevicelink/util/AndroidTools.java
@@ -2,9 +2,16 @@ package com.smartdevicelink.util;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+
+import com.smartdevicelink.transport.TransportConstants;
+
+import java.util.HashMap;
+import java.util.List;
public class AndroidTools {
/**
@@ -22,4 +29,24 @@ public class AndroidTools {
}
return false;
}
+ /**
+ * Get all SDL enabled apps. If the package name is null, it will return all apps. However, if the package name is included, the
+ * resulting hash map will not include the app with that package name.
+ * @param context
+ * @param myPackageName
+ * @return
+ */
+ public static HashMap<String,ResolveInfo> getSdlEnabledApps(Context context, String myPackageName){
+ Intent intent = new Intent(TransportConstants.START_ROUTER_SERVICE_ACTION);
+ List<ResolveInfo> infos = context.getPackageManager().queryBroadcastReceivers(intent, 0);
+ HashMap<String,ResolveInfo> sdlMultiList = new HashMap<String,ResolveInfo>();
+ for(ResolveInfo info: infos){
+ if(info.activityInfo.applicationInfo.packageName.equals(myPackageName)){
+ continue; //Ignoring my own package
+ }
+ sdlMultiList.put(info.activityInfo.packageName, info);
+ }
+ return sdlMultiList;
+ }
+
}
diff --git a/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java b/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java
new file mode 100644
index 000000000..c115d046c
--- /dev/null
+++ b/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java
@@ -0,0 +1,141 @@
+package com.smartdevicelink.util;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.os.Handler;
+import android.util.Log;
+
+import com.smartdevicelink.transport.SdlRouterService;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+import static com.smartdevicelink.transport.TransportConstants.BIND_LOCATION_CLASS_NAME_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.BIND_LOCATION_PACKAGE_NAME_EXTRA;
+import static com.smartdevicelink.transport.TransportConstants.SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME;
+
+/**
+ * Created by Joey Grover on 8/18/17.
+ */
+
+public class ServiceFinder {
+ public static final String TAG = ServiceFinder.class.getSimpleName();
+
+ private static final int TIMEOUT = 1000;
+ final String receiverLocation;
+ final Context context;
+ final ServiceFinderCallback callback;
+ final Vector<ComponentName> services;
+ final HashMap<String, ResolveInfo> sdlMultiMap;
+ final Handler timeoutHandler;
+ final Runnable timeoutRunnable;
+
+
+ public ServiceFinder(Context context, String packageName, final ServiceFinderCallback callback) {
+ this.receiverLocation = packageName + ".ServiceFinder";
+ this.context = context.getApplicationContext();
+ this.callback = callback;
+ this.services = new Vector<>();
+
+ this.sdlMultiMap = AndroidTools.getSdlEnabledApps(context, packageName);
+
+ this.context.registerReceiver(mainServiceReceiver, new IntentFilter(this.receiverLocation));
+
+ timeoutRunnable = new Runnable() {
+ @Override
+ public void run() {
+ onFinished();
+ }
+ };
+ timeoutHandler = new Handler();
+ timeoutHandler.postDelayed(timeoutRunnable, TIMEOUT + (50 * packageName.length()));
+
+ //Send out our broadcast
+ context.sendBroadcast(createQueryIntent(this.receiverLocation));
+
+
+ }
+
+ BroadcastReceiver mainServiceReceiver = new BroadcastReceiver() {
+ private final Object LIST_LOCK = new Object();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "Received intent " + intent);
+ if (intent != null) {
+ String packageName = intent.getStringExtra(BIND_LOCATION_PACKAGE_NAME_EXTRA);
+ String className = intent.getStringExtra(BIND_LOCATION_CLASS_NAME_EXTRA);
+ Log.d(TAG, "Received intent from package: " + packageName + ". Classname: " + className);
+ synchronized (LIST_LOCK) {
+ //Add to running services
+ services.add(new ComponentName(packageName, className));
+ //Remove from our waiting for response list
+ sdlMultiMap.remove(packageName);
+
+ //If list is empty, return to callback and unregister
+ if (sdlMultiMap.isEmpty() && callback != null) {
+ timeoutHandler.removeCallbacks(timeoutRunnable);
+ onFinished();
+ }
+ }
+ }
+ }
+ };
+
+ private void onFinished() {
+ if (callback != null) {
+ callback.onComplete(services);
+ }
+ context.unregisterReceiver(mainServiceReceiver);
+
+ }
+
+// /**
+// * Get all SDL enabled apps. If the package name is null, it will return all apps. However, if the package name is included, the
+// * resulting hash map will not include the app with that package name.
+// *
+// * @param context
+// * @param packageName
+// * @return
+// */
+// public static HashMap<String, ResolveInfo> getSdlEnabledApps(Context context, String packageName) {
+// Intent intent = new Intent(TransportConstants.START_ROUTER_SERVICE_ACTION);
+// PackageManager manager = context.getPackageManager();
+// List<ResolveInfo> infos = manager.queryBroadcastReceivers(intent, 0);
+// HashMap<String, ResolveInfo> sdlMultiMap = new HashMap<String, ResolveInfo>();
+// for (ResolveInfo info : infos) {
+// //Log.d(TAG, "Sdl enabled app: " + info.activityInfo.packageName);
+// if (info.activityInfo.applicationInfo.packageName.equals(packageName)) {
+// //Log.d(TAG, "Ignoring my own package");
+// continue;
+// }
+//
+// sdlMultiMap.put(info.activityInfo.packageName, info);
+// try {
+// ServiceInfo[] services = manager.getPackageInfo(info.activityInfo.applicationInfo.packageName, PackageManager.GET_SERVICES).services;
+// for (int i = 0; i < services.length; i++) {
+// Log.d(TAG, "Found : " + services[i].name);
+// }
+// } catch (PackageManager.NameNotFoundException e) {
+// e.printStackTrace();
+// }
+// }
+// return sdlMultiMap;
+// }
+
+ private static Intent createQueryIntent(String receiverLocation) {
+ Intent intent = new Intent();
+ intent.setAction(SdlRouterService.REGISTER_WITH_ROUTER_ACTION);
+ intent.putExtra(SEND_PACKET_TO_APP_LOCATION_EXTRA_NAME, receiverLocation);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ return intent;
+ }
+
+ public interface ServiceFinderCallback {
+ void onComplete(Vector<ComponentName> routerServices);
+ }
+}