From 3b81f54432a97c0e986f13366bcec2b2636b7314 Mon Sep 17 00:00:00 2001 From: Julian Kast Date: Thu, 13 Nov 2025 15:26:44 -0500 Subject: [PATCH 1/8] Update to gradle version 8.13 and target API level 36 (#1886) * Remove package from manifest and put in build.gradle * Update gradle version to 8.2.2 * Update gradle version to 8.2.2 * update maven plugin * add buildFeatures aidl as suggested by AGP update assistant * Formatting * add androidTestImplementation 'androidx.test:rules:1.5.0' to test permission in unit test, update unit test imports * Add permissions queries for routerService to Android test manifest * Add TestSdlReceiver for unit test * Reset SDK_INT version in AudioStreamManagerTest after it is changed for tests * update manager layer test sleep calls to 1 sec * Update DeviceUtil.isEmulator to catch new emulator for ci checks * grant BLUETOOTH_CONNECT for TransportManagerTests * grant BLUETOOTH_CONNECT permission for MediaStreamingStatusTests * Ignore TransportBrokerTest with note to have an app with a running RouterService for test to work. * MultiplexBluetoothTransportTest testStateTransitions only check state if device is not an emulator, New emulator actually works, so to prevent incompatibility with older emulators only check on actual devices * Starting with API 30 we can not use reflection to fake NetworkCapabilities, only doing certain checks on API levels less then 30 for WiFiSocketFactoryTest * update comment for WiFiSocketFactoryTest * Update yml to target proper API level, use newer JDK and beef up emulator * Update targetSdkVersion to 36 and minSdkVersion to 21 * Update gradle to 8.13 * update dependencies * update CI * downgrade api level on CI * try arm runner with api level 36 * update android test to use arm based emulator for api 36 * update to run on ubuntu with x86_64 android image * change back to mac * beef up emulator * update emulator options * Use ubuntu runner * improve emulator boot time * use google_apis for the emulator type * Add enable kvm to make Android emulator run faster --- .github/workflows/android.yml | 32 +++++++++++----- android/build.gradle | 2 +- android/gradle.properties | 3 ++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/hello_sdl_android/build.gradle | 11 +++--- .../src/main/AndroidManifest.xml | 3 +- android/sdl_android/build.gradle | 38 +++++++++++-------- .../src/androidTest/AndroidManifest.xml | 28 ++++++++++++-- .../com/smartdevicelink/TestSdlReceiver.java | 14 +++++++ .../audio/AudioStreamManagerTest.java | 32 ++++++++++++++++ .../screen/SoftButtonManagerTests.java | 2 +- .../PreloadPresentChoicesOperationTests.java | 2 +- .../PresentKeyboardOperationTests.java | 2 +- .../screen/menu/MenuManagerTests.java | 2 +- .../MultiplexBluetoothTransportTest.java | 4 +- .../test/transport/WiFiSocketFactoryTest.java | 20 +++++++--- .../smartdevicelink/test/util/DeviceUtil.java | 1 + .../transport/TransportBrokerTest.java | 2 + .../transport/TransportManagerTests.java | 7 ++++ .../util/MediaStreamingStatusTests.java | 5 +++ .../sdl_android/src/main/AndroidManifest.xml | 3 +- 21 files changed, 163 insertions(+), 52 deletions(-) create mode 100644 android/sdl_android/src/androidTest/java/com/smartdevicelink/TestSdlReceiver.java diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index db6fc40aa9..029d33910c 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -4,7 +4,7 @@ on: [push, pull_request, workflow_dispatch] jobs: test_Android: - runs-on: macOS-latest + runs-on: ubuntu-latest steps: - name: Checkout @@ -15,15 +15,29 @@ jobs: - name: Setup JDK uses: actions/setup-java@v1 with: - java-version: 11 - - - name: Sdl Android Tests - # For more info, please check out: https://github.com/marketplace/actions/android-emulator-runner + java-version: 17 + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + ls -l /dev/kvm || true + + - name: SDL Android Tests uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 29 - script: ./android/gradlew -p ./android :sdl_android:connectedCheck - + api-level: 36 + target: google_apis + arch: x86_64 + profile: pixel_7 + ram-size: 2048M + disk-size: 4096M + disable-animations: true + emulator-boot-timeout: 1200 + emulator-options: "-no-window -no-snapshot -no-audio" + script: ./android/gradlew -p ./android :sdl_android:connectedDebugAndroidTest + - name: Hello Sdl Android Tests run: ./android/gradlew -p ./android/hello_sdl_android test @@ -33,7 +47,7 @@ jobs: yml: ./codecov.yml test_Java: - runs-on: macOS-latest + runs-on: ubuntu-latest steps: - name: Checkout diff --git a/android/build.gradle b/android/build.gradle index b6c2dd894d..b46d5156f3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.13.0' // NOTE: Do not place your application dependencies here; they belong diff --git a/android/gradle.properties b/android/gradle.properties index 9e6fce102d..0f2dd31508 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -10,6 +10,9 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonFinalResIds=false +android.nonTransitiveRClass=false android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index c1077f26d3..83a84690dc 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip diff --git a/android/hello_sdl_android/build.gradle b/android/hello_sdl_android/build.gradle index a3f5563248..11a59919aa 100755 --- a/android/hello_sdl_android/build.gradle +++ b/android/hello_sdl_android/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 34 + compileSdkVersion 36 defaultConfig { applicationId "com.sdl.hellosdlandroid" - minSdkVersion 16 - targetSdkVersion 34 + minSdkVersion 21 + targetSdkVersion 36 versionCode 1 versionName "1.0" resValue "string", "app_name", "Hello Sdl Android" @@ -61,6 +61,7 @@ android { lintOptions { disable 'GoogleAppIndexingWarning' } + namespace 'com.sdl.hellosdlandroid' } @@ -69,7 +70,7 @@ dependencies { androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.appcompat:appcompat:1.7.1' implementation project(path: ':sdl_android') - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.2' } \ No newline at end of file diff --git a/android/hello_sdl_android/src/main/AndroidManifest.xml b/android/hello_sdl_android/src/main/AndroidManifest.xml index cdb26819db..2a0742fb3e 100755 --- a/android/hello_sdl_android/src/main/AndroidManifest.xml +++ b/android/hello_sdl_android/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> + - + @@ -13,10 +12,33 @@ android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.smartdevicelink.test" /> + + + + + + + + + + + + + + + + + + + + diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/TestSdlReceiver.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/TestSdlReceiver.java new file mode 100644 index 0000000000..91789a6598 --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/TestSdlReceiver.java @@ -0,0 +1,14 @@ +package com.smartdevicelink; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * Added so we pass IntegrationValidator when running unit test. + */ +public class TestSdlReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + } +} \ No newline at end of file diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java index d81b9ccc62..8c583b3062 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/audio/AudioStreamManagerTest.java @@ -134,99 +134,131 @@ public void onComplete(boolean success) { } public void testWithSquareSampleAudio16BitAnd8KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd16KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd22KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd44KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd8KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd16KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd22KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd44KhzApi16() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 16); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd8KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd16KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd22KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio16BitAnd44KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._16_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.SIGNED_16_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd8KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._8KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(8000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd16KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._16KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(16000, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd22KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._22KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(22050, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } public void testWithSquareSampleAudio8BitAnd44KhzApi21() throws Exception { + int versionCode = Build.VERSION.SDK_INT; setFinalStatic(Build.VERSION.class.getField("SDK_INT"), 21); AudioPassThruCapabilities audioPassThruCapabilities = new AudioPassThruCapabilities(SamplingRate._44KHZ, BitsPerSample._8_BIT, AudioType.PCM); runFullAudioManagerDecodeFlowWithSquareSampleAudio(44100, SampleType.UNSIGNED_8_BIT, audioPassThruCapabilities); + setFinalStatic(Build.VERSION.class.getField("SDK_INT"), versionCode); } private int testFullAudioManagerDecodeFlowCorrectCounter = 0; diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java index 7e0890e18a..8e2f3326f1 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/SoftButtonManagerTests.java @@ -178,7 +178,7 @@ public Void answer(InvocationOnMock invocation) { private void sleep() { try { - Thread.sleep(100); + Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadPresentChoicesOperationTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadPresentChoicesOperationTests.java index 8a8b8c64eb..59fd5ad4cf 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadPresentChoicesOperationTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PreloadPresentChoicesOperationTests.java @@ -246,7 +246,7 @@ public void testSetSelectedCellWithId() { private void sleep() { try { - Thread.sleep(100); + Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java index 5d6df79587..60d6b6bf15 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/PresentKeyboardOperationTests.java @@ -129,7 +129,7 @@ public void testGetPerformInteraction() { private void sleep() { try { - Thread.sleep(100); + Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java index 863f0b4d9f..f8015ef496 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java @@ -785,7 +785,7 @@ private List filterMenuCellsWithStatusList(List menuCells, L private void sleep() { try { - Thread.sleep(250); + Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/MultiplexBluetoothTransportTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/MultiplexBluetoothTransportTest.java index 5d9f752681..aa2d32dfd5 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/MultiplexBluetoothTransportTest.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/MultiplexBluetoothTransportTest.java @@ -52,9 +52,7 @@ public void handleMessage(Message msg) { assertEquals(bluetooth.getState(), MultiplexBluetoothTransport.STATE_NONE); bluetooth.start(); - if (DeviceUtil.isEmulator()) { - assertEquals(bluetooth.getState(), MultiplexBluetoothTransport.STATE_NONE); - } else { + if (!DeviceUtil.isEmulator()) { assertEquals(bluetooth.getState(), MultiplexBluetoothTransport.STATE_LISTEN); } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/WiFiSocketFactoryTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/WiFiSocketFactoryTest.java index 8cbaa3c72f..41f33b38d9 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/WiFiSocketFactoryTest.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/transport/WiFiSocketFactoryTest.java @@ -111,8 +111,8 @@ private static NetworkCapabilities createNetworkCapabilitiesWithTransport(int tr // Since NetworkCapabilities class is 'final', we cannot create its mock. To create a dummy // instance, here we use reflection to call its constructor and a method that are marked // with "@hide". - // It is possible that these methods will not be available in a future version of Android. - // In that case we need to update our code accordingly. + // Starting in API level 30, this no longer works. + // There is not a good way to bypass this so some test will check API level Class c = NetworkCapabilities.class; try { Method addTransportTypeMethod = c.getMethod("addTransportType", int.class); @@ -176,7 +176,9 @@ public void testWithWiFiNetwork() { Socket ret = WiFiSocketFactory.createSocket(mMockContext); assertNotNull("createSocket() should always return a Socket instance", ret); - assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + } } // test the case where SDK_INT is less than 21 @@ -272,7 +274,9 @@ public void testNetworkListHasNull() { Socket ret = WiFiSocketFactory.createSocket(mMockContext); assertNotNull("createSocket() should always return a Socket instance", ret); - assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + } } // test the case where the phone isn't connected to Wi-Fi network @@ -316,7 +320,9 @@ public void testSocketFactoryNull2() { Socket ret = WiFiSocketFactory.createSocket(mMockContext); assertNotNull("createSocket() should always return a Socket instance", ret); - assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + } } // test the case where we get an exception with SocketFactory.createSocket() @@ -349,6 +355,8 @@ public void testFactoryReturnsException2() throws IOException { Socket ret = WiFiSocketFactory.createSocket(mMockContext); assertNotNull("createSocket() should always return a Socket instance", ret); - assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { + assertEquals("Returned Socket should be created through SocketFactory", mWiFiBoundSocket, ret); + } } } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/util/DeviceUtil.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/util/DeviceUtil.java index 389403eafb..c74c3a3b44 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/util/DeviceUtil.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/test/util/DeviceUtil.java @@ -10,6 +10,7 @@ public static boolean isEmulator() { || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for") || Build.MANUFACTURER.contains("Genymotion") + || Build.DEVICE.startsWith("emu") || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || (Build.BRAND.startsWith("Android") && Build.DEVICE.startsWith("generic")) || (Build.PRODUCT != null && Build.PRODUCT.startsWith("sdk_google_phone")) diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportBrokerTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportBrokerTest.java index 4ee6926aa7..99abb67ea6 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportBrokerTest.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportBrokerTest.java @@ -13,6 +13,7 @@ import com.smartdevicelink.test.util.DeviceUtil; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -22,6 +23,7 @@ import static junit.framework.TestCase.assertTrue; @RunWith(AndroidJUnit4.class) +@Ignore // MUST HAVE AN SDL APP WITH A ROUTER SERVICE RUNNING ON PHONE TO RUN THESE TEST public class TransportBrokerTest { //FIXME this test class needs to be fixed. At this point these tests are not helpful RouterServiceValidator rsvp; // public TransportBrokerThread(Context context, String appId, ComponentName service){ diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportManagerTests.java index 06a31bc59f..42d09c0537 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/transport/TransportManagerTests.java @@ -1,9 +1,12 @@ package com.smartdevicelink.transport; +import android.Manifest; import android.content.ComponentName; +import android.os.Build; import android.os.Looper; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.GrantPermissionRule; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.protocol.SdlPacketFactory; @@ -13,6 +16,7 @@ import com.smartdevicelink.transport.utl.TransportRecord; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +33,9 @@ @RunWith(AndroidJUnit4.class) public class TransportManagerTests { + + @Rule + public GrantPermissionRule btRuntimePermissionRule = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? GrantPermissionRule.grant(Manifest.permission.BLUETOOTH_CONNECT) : null; MultiplexTransportConfig config; final TransportRecord defaultBtRecord = new TransportRecord(TransportType.BLUETOOTH, "12:34:56:78:90"); final ComponentName routerServiceComponentName = new ComponentName("com.smartdevicelink.test", "com.smartdevicelink.test.SdlRouterService"); diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/util/MediaStreamingStatusTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/util/MediaStreamingStatusTests.java index b2d1cf890c..635be1dcaa 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/util/MediaStreamingStatusTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/util/MediaStreamingStatusTests.java @@ -1,11 +1,13 @@ package com.smartdevicelink.util; +import android.Manifest; import android.content.Context; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.os.Build; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.GrantPermissionRule; import com.smartdevicelink.managers.SdlManager; import com.smartdevicelink.managers.SdlManagerListener; @@ -14,6 +16,7 @@ import com.smartdevicelink.transport.MultiplexTransportConfig; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -35,6 +38,8 @@ public class MediaStreamingStatusTests { + @Rule + public GrantPermissionRule btRuntimePermissionRule = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? GrantPermissionRule.grant(Manifest.permission.BLUETOOTH_CONNECT) : null; @Mock private AudioManager audioManager = mock(AudioManager.class); diff --git a/android/sdl_android/src/main/AndroidManifest.xml b/android/sdl_android/src/main/AndroidManifest.xml index 4efa349fb7..a4f5ddee90 100644 --- a/android/sdl_android/src/main/AndroidManifest.xml +++ b/android/sdl_android/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + From 9bb57bd2f2cc158fa89d6c4f86057f599856873b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Thu, 13 Nov 2025 15:38:31 -0500 Subject: [PATCH 2/8] Update version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3b867ccd76..edb1d397cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.7.0 \ No newline at end of file +5.8.0 \ No newline at end of file From 3195811473b9152cb54ff0762539f52593b1eb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Thu, 13 Nov 2025 15:50:10 -0500 Subject: [PATCH 3/8] Update versionCode --- android/sdl_android/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/sdl_android/build.gradle b/android/sdl_android/build.gradle index 8a577fd8bd..d3d63462bb 100644 --- a/android/sdl_android/build.gradle +++ b/android/sdl_android/build.gradle @@ -5,6 +5,8 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 36 + versionCode 27 + versionName new File(projectDir.path, ('/../../VERSION')).text.trim() buildConfigField "String", "VERSION_NAME", '\"' + versionName + '\"' resValue "string", "SDL_LIB_VERSION", '\"' + versionName + '\"' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' From 0615b5c1ddd32a6df962d11b94b5eeb7dd4ef148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Fri, 14 Nov 2025 13:38:42 -0500 Subject: [PATCH 4/8] update gradle.properties for release --- android/sdl_android/gradle.properties | 9 --------- 1 file changed, 9 deletions(-) diff --git a/android/sdl_android/gradle.properties b/android/sdl_android/gradle.properties index d720ac7959..c5a1bdcb4c 100644 --- a/android/sdl_android/gradle.properties +++ b/android/sdl_android/gradle.properties @@ -16,15 +16,6 @@ POM_LICENCE_NAME=BSD 3-Clause POM_LICENCE_URL=https://opensource.org/licenses/BSD-3-Clause POM_LICENCE_DIST=repo -RELEASE_REPOSITORY_URL=https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ -SNAPSHOT_REPOSITORY_URL=https://s01.oss.sonatype.org/content/repositories/snapshots/ - POM_DEVELOPER_ID= POM_DEVELOPER_NAME= POM_DEVELOPER_URL= - -signing.keyId= -signing.password= -signing.secretKeyRingFile= -SONATYPE_NEXUS_USERNAME= -SONATYPE_NEXUS_PASSWORD= \ No newline at end of file From 4ae1d5ebb7e3f4fb9bbd3e5496491a4e20812768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Fri, 14 Nov 2025 13:47:31 -0500 Subject: [PATCH 5/8] update build.gradle to support maven central upload --- android/sdl_android/build.gradle | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/android/sdl_android/build.gradle b/android/sdl_android/build.gradle index d3d63462bb..1ca82ca240 100644 --- a/android/sdl_android/build.gradle +++ b/android/sdl_android/build.gradle @@ -1,4 +1,21 @@ -apply plugin: 'com.android.library' +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + } +} + +plugins { + id "com.android.library" + id "com.vanniktech.maven.publish" version "0.34.0" +} + +mavenPublishing { + publishToMavenCentral() + signAllPublications() +} android { compileSdkVersion 36 @@ -66,15 +83,3 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0' androidTestImplementation 'androidx.test.espresso:espresso-intents:3.7.0' } - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' - classpath 'com.vanniktech:gradle-maven-publish-plugin:0.34.0' - } -} - -apply plugin: "com.vanniktech.maven.publish" From b630ab7e441e709b9053366935cb91ba43fd45d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Fri, 14 Nov 2025 13:52:43 -0500 Subject: [PATCH 6/8] update version for javaSE --- .../javaSE/src/main/java/com/smartdevicelink/BuildConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java b/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java index 50d96116e8..0fe321265c 100644 --- a/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java +++ b/javaSE/javaSE/src/main/java/com/smartdevicelink/BuildConfig.java @@ -32,5 +32,5 @@ // THIS FILE IS AUTO GENERATED, DO NOT MODIFY!! public final class BuildConfig { - public static final String VERSION_NAME = "5.7.0"; + public static final String VERSION_NAME = "5.8.0"; } \ No newline at end of file From 2d8a46017516b4c7a829b62e3815df232f322895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Mon, 17 Nov 2025 13:54:43 -0500 Subject: [PATCH 7/8] Make updates for vanniktech plugin --- android/sdl_android/build.gradle | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/android/sdl_android/build.gradle b/android/sdl_android/build.gradle index 1ca82ca240..c97d231d8b 100644 --- a/android/sdl_android/build.gradle +++ b/android/sdl_android/build.gradle @@ -9,9 +9,12 @@ buildscript { plugins { id "com.android.library" - id "com.vanniktech.maven.publish" version "0.34.0" + id "com.vanniktech.maven.publish" version "0.35.0" } +group = "com.smartdevicelink" +version = file("../../VERSION").text.trim() + mavenPublishing { publishToMavenCentral() signAllPublications() @@ -83,3 +86,11 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0' androidTestImplementation 'androidx.test.espresso:espresso-intents:3.7.0' } + +afterEvaluate { + tasks.named("sourceReleaseJar") { + exclude { details -> + details.file.toPath().toString().contains("/generated/") + } + } +} \ No newline at end of file From 3a8121de098938908f75d9c70ff041e1d6139f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJKAST=E2=80=9D?= Date: Mon, 17 Nov 2025 13:58:12 -0500 Subject: [PATCH 8/8] update changelog --- CHANGELOG.md | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da36c3168..506d62ae55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 5.7.0 Release Notes +# 5.8.0 Release Notes ## Summary: @@ -6,44 +6,8 @@ |---|---| | **Protocol** | 5.4.1 | | **RPC** | 8.0.0 | -| **Tested Targeting** | Android 34 | +| **Tested Targeting** | Android 36 | ## Bug Fix / Enhancements: -- [Add pending intent to ping intents] (https://github.com/smartdevicelink/sdl_java_suite/pull/1844 - -- [Fixes #1845 typo in SdlBroadcastReceiver for uncaughtException handler](https://github.com/smartdevicelink/sdl_java_suite/pull/1846 - -- [Bugfix/issue #1842 - NPE in BaseTextAndGraphicsManager](https://github.com/smartdevicelink/sdl_java_suite/pull/1847 - -- [Fix case for UncaughtExceptionHandler in SdlBroadcastReceiver for RemoteServiceException](https://github.com/smartdevicelink/sdl_java_suite/pull/1849 - -- [Update gradle to 7.4.2](https://github.com/smartdevicelink/sdl_java_suite/pull/1853 - -- [Fix NPE in SdlRouterService](https://github.com/smartdevicelink/sdl_java_suite/pull/1870 - -- [Bugfix/issue 1867 Bluetooth notification error fix](https://github.com/smartdevicelink/sdl_java_suite/pull/1868 - -- [Clean LifecycleManager before closing](https://github.com/smartdevicelink/sdl_java_suite/pull/1866 - -- [Move router service message sending to its own thread](https://github.com/smartdevicelink/sdl_java_suite/pull/1871 - -- [Bugfix/issue 1863 update gradle build variants for hello_sdl](https://github.com/smartdevicelink/sdl_java_suite/pull/1864 - -- [Android 14 add package to PendingIntents in RouterService](https://github.com/smartdevicelink/sdl_java_suite/pull/1862 - -- [Android 14 Runtime registered broadcast receivers export behavior](https://github.com/smartdevicelink/sdl_java_suite/pull/1858 - -- [Add logic to handle RAI response failure](https://github.com/smartdevicelink/sdl_java_suite/pull/1873 - -- [Android 14 foreground service type required](https://github.com/smartdevicelink/sdl_java_suite/pull/1860 - -- [Update integration validator with latest permissions and checks for exported](https://github.com/smartdevicelink/sdl_java_suite/pull/1875 - -- [Fix SDLLockScreenActivityEspressoTest for newer devices](https://github.com/smartdevicelink/sdl_java_suite/pull/1877 - -- [Remove only app logic for device listener start](https://github.com/smartdevicelink/sdl_java_suite/pull/1879) - -- [Fix NPE in TransportBroker](https://github.com/smartdevicelink/sdl_java_suite/pull/1882) - -**Full Changelog**: https://github.com/smartdevicelink/sdl_java_suite/compare/5.6.1...RC_5.7.0 \ No newline at end of file +- [Update to gradle version 8.13 and target API level 36] (https://github.com/smartdevicelink/sdl_java_suite/pull/1886)