From 85ae1a5225e4e02339b6f8ec1ee70671ff278790 Mon Sep 17 00:00:00 2001 From: Ada Date: Fri, 15 Jul 2022 01:00:37 +0800 Subject: [PATCH 1/7] Implement PendingIntentCompat to enforce mutability flag --- .../location/gps/gnsslogger/MainActivity.java | 9 +- .../gps/gnsslogger/PendingIntentCompat.java | 142 ++++++++++++++++++ 2 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java index f385309..dbbebd7 100755 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java @@ -16,7 +16,6 @@ package com.google.android.apps.location.gps.gnsslogger; - import android.Manifest; import android.app.Activity; import android.app.PendingIntent; @@ -141,12 +140,8 @@ protected void onCreate(Bundle savedInstanceState) { protected PendingIntent createActivityDetectionPendingIntent() { Intent intent = new Intent(this, DetectedActivitiesIntentReceiver.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - return PendingIntent.getBroadcast(this, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - } else { - return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } + return PendingIntentCompat.getBroadcast( + this, 0, intent, true, PendingIntent.FLAG_UPDATE_CURRENT); } private synchronized void buildGoogleApiClient() { diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java new file mode 100644 index 0000000..5c418d4 --- /dev/null +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.apps.location.gps.gnsslogger; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_MUTABLE; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import androidx.annotation.RequiresApi; + +/** Helper for accessing features in {@link PendingIntent}. */ +public class PendingIntentCompat { + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. + */ + public static PendingIntent getActivities( + Context context, + int requestCode, + Intent[] intents, + boolean isMutable, + int flags, + Bundle options) { + return PendingIntent.getActivities( + context, requestCode, intents, addMutabilityFlags(isMutable, flags), options); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. + */ + public static PendingIntent getActivities( + Context context, int requestCode, Intent[] intents, boolean isMutable, int flags) { + return PendingIntent.getActivities( + context, requestCode, intents, addMutabilityFlags(isMutable, flags)); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getActivity(Context, int, Intent, int)}. + */ + public static PendingIntent getActivity( + Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + return PendingIntent.getActivity( + context, requestCode, intent, addMutabilityFlags(isMutable, flags)); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getActivity(Context, int, Intent, int, Bundle)}. + */ + public static PendingIntent getActivity( + Context context, + int requestCode, + Intent intent, + boolean isMutable, + int flags, + Bundle options) { + return PendingIntent.getActivity( + context, requestCode, intent, addMutabilityFlags(isMutable, flags), options); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getBroadcast(Context, int, Intent, int)}. + */ + public static PendingIntent getBroadcast( + Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + return PendingIntent.getBroadcast( + context, requestCode, intent, addMutabilityFlags(isMutable, flags)); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getForegroundService(Context, int, Intent, int)} . + */ + @RequiresApi(api = Build.VERSION_CODES.O) + public static PendingIntent getForegroundService( + Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + return PendingIntent.getForegroundService( + context, requestCode, intent, addMutabilityFlags(isMutable, flags)); + } + + /** + * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See {@link + * PendingIntent#getService(Context, int, Intent, int)}. + */ + public static PendingIntent getService( + Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + return PendingIntent.getService( + context, requestCode, intent, addMutabilityFlags(isMutable, flags)); + } + + private static int addMutabilityFlags(boolean isMutable, int flags) { + if (isMutable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + flags |= FLAG_MUTABLE; + } + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + flags |= FLAG_IMMUTABLE; + } + } + + return flags; + } + + private PendingIntentCompat() {} +} From 71873f84f95a5c00404249fcd8b5cf6bc8a91ee0 Mon Sep 17 00:00:00 2001 From: Ada Date: Fri, 15 Jul 2022 01:59:04 +0800 Subject: [PATCH 2/7] Add parameter hint comments --- .../android/apps/location/gps/gnsslogger/MainActivity.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java index dbbebd7..a500751 100755 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java @@ -141,7 +141,11 @@ protected void onCreate(Bundle savedInstanceState) { protected PendingIntent createActivityDetectionPendingIntent() { Intent intent = new Intent(this, DetectedActivitiesIntentReceiver.class); return PendingIntentCompat.getBroadcast( - this, 0, intent, true, PendingIntent.FLAG_UPDATE_CURRENT); + /* context= */ this, + /* requestCode= */ 0, + intent, + /* isMutable= */ true, + PendingIntent.FLAG_UPDATE_CURRENT); } private synchronized void buildGoogleApiClient() { From c77f0ae6a553adc53d262f6516f0faca705f4100 Mon Sep 17 00:00:00 2001 From: Ada Date: Tue, 19 Jul 2022 17:22:34 +0800 Subject: [PATCH 3/7] Add unit test for PendingIntentCompat --- GNSSLogger/app/build.gradle | 10 +- .../gps/gnsslogger/ExampleUnitTest.java | 17 --- .../gnsslogger/PendingIntentCompatTest.java | 110 ++++++++++++++++++ 3 files changed, 119 insertions(+), 18 deletions(-) delete mode 100644 GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java create mode 100644 GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle index e2b770b..51eb21c 100644 --- a/GNSSLogger/app/build.gradle +++ b/GNSSLogger/app/build.gradle @@ -26,6 +26,11 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + testOptions { + unitTests { + includeAndroidResources = true + } + } } dependencies { @@ -38,8 +43,11 @@ dependencies { implementation files('libs/achartengine-1.2.0.jar') implementation("com.google.guava:guava:31.1-android") implementation 'com.google.android.material:material:1.6.1' + implementation 'androidx.test:core:1.4.0' + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.robolectric:robolectric:4.8' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.ext:junit:1.1.3' - testImplementation 'junit:junit:4.13.2' + testImplementation "com.google.truth:truth:1.1.3" implementation "androidx.core:core:1.8.0" } \ No newline at end of file diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java deleted file mode 100644 index 00efbce..0000000 --- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.google.android.apps.location.gps.gnsslogger; - -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java new file mode 100644 index 0000000..877e7f2 --- /dev/null +++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java @@ -0,0 +1,110 @@ +package com.google.android.apps.location.gps.gnsslogger; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static com.google.common.truth.Truth.assertThat; +import static org.robolectric.Shadows.shadowOf; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import androidx.test.core.app.ApplicationProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPendingIntent; + +/** Unit test for {@link PendingIntentCompat}. */ +@RunWith(RobolectricTestRunner.class) +public class PendingIntentCompatTest { + private final Context context = ApplicationProvider.getApplicationContext(); + + @Config(sdk = Build.VERSION_CODES.LOLLIPOP_MR1) + @Test + public void getActivities_notMutableOnPreM() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + + @Config(sdk = Build.VERSION_CODES.M) + @Test + public void getActivities_notMutableOnMPlus() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getActivities_notMutableOnPreS() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getActivities_notMutableOnSPlus() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getService() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isService()).isTrue(); + } + + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getBroadcast() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + assertThat(shadow.isBroadcast()).isTrue(); + } +} From 3a08997939b756dc6194a792fff476c68f66726f Mon Sep 17 00:00:00 2001 From: Ada Date: Tue, 19 Jul 2022 17:45:23 +0800 Subject: [PATCH 4/7] Add a few missing test cases and adjust the code format --- GNSSLogger/app/build.gradle | 5 -- .../gnsslogger/PendingIntentCompatTest.java | 87 +++++++++++++++++-- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle index 51eb21c..439966b 100644 --- a/GNSSLogger/app/build.gradle +++ b/GNSSLogger/app/build.gradle @@ -26,11 +26,6 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - testOptions { - unitTests { - includeAndroidResources = true - } - } } dependencies { diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java index 877e7f2..b99ec36 100644 --- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java +++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java @@ -1,6 +1,5 @@ package com.google.android.apps.location.gps.gnsslogger; -import static android.app.PendingIntent.FLAG_IMMUTABLE; import static com.google.common.truth.Truth.assertThat; import static org.robolectric.Shadows.shadowOf; @@ -30,7 +29,12 @@ public void getActivities_notMutableOnPreM() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isActivityIntent()).isTrue(); assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); assertThat(shadow.getRequestCode()).isEqualTo(requestCode); @@ -45,7 +49,12 @@ public void getActivities_notMutableOnMPlus() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isActivityIntent()).isTrue(); assertThat(shadow.getFlags()) .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); @@ -61,12 +70,58 @@ public void getActivities_notMutableOnPreS() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isActivityIntent()).isTrue(); assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getActivities_MutableOnPreS() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, + requestCode, + intents, + /* isMutable= */ true, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + + @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getActivities_MutableOnSPlus() { + int requestCode = 7465; + Intent[] intents = new Intent[] {}; + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivities( + context, + requestCode, + intents, + /* isMutable= */ true, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); + assertThat(shadow.isActivityIntent()).isTrue(); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + assertThat(shadow.getRequestCode()).isEqualTo(requestCode); + } + @Config(sdk = Build.VERSION_CODES.R) @Test public void getActivities_notMutableOnSPlus() { @@ -76,9 +131,15 @@ public void getActivities_notMutableOnSPlus() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isActivityIntent()).isTrue(); - assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } @@ -91,7 +152,12 @@ public void getService() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isService()).isTrue(); } @@ -104,7 +170,12 @@ public void getBroadcast() { ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getActivities( - context, requestCode, intents, false, PendingIntent.FLAG_UPDATE_CURRENT, options)); + context, + requestCode, + intents, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT, + options)); assertThat(shadow.isBroadcast()).isTrue(); } } From 4d77286c1b0e07d17cb8da510e5850b80388e697 Mon Sep 17 00:00:00 2001 From: Ada Date: Wed, 20 Jul 2022 15:54:01 +0800 Subject: [PATCH 5/7] Fix mistakes in test cases and add annotions in PendingIntentCompat --- GNSSLogger/app/build.gradle | 2 +- .../gps/gnsslogger/PendingIntentCompat.java | 58 ++++++--- .../gnsslogger/PendingIntentCompatTest.java | 122 ++++++++++++------ 3 files changed, 121 insertions(+), 61 deletions(-) diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle index 439966b..3eedd6e 100644 --- a/GNSSLogger/app/build.gradle +++ b/GNSSLogger/app/build.gradle @@ -40,7 +40,7 @@ dependencies { implementation 'com.google.android.material:material:1.6.1' implementation 'androidx.test:core:1.4.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.robolectric:robolectric:4.8' + testImplementation 'org.robolectric:robolectric:4.8.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.ext:junit:1.1.3' testImplementation "com.google.truth:truth:1.1.3" diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java index 5c418d4..cd4c460 100644 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java @@ -19,11 +19,13 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; +import android.annotation.SuppressLint; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; /** Helper for accessing features in {@link PendingIntent}. */ @@ -35,13 +37,13 @@ public class PendingIntentCompat { * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. */ - public static PendingIntent getActivities( - Context context, + public static @NonNull PendingIntent getActivities( + @NonNull Context context, int requestCode, - Intent[] intents, + @NonNull @SuppressLint("ArrayReturn") Intent[] intents, boolean isMutable, int flags, - Bundle options) { + @NonNull Bundle options) { return PendingIntent.getActivities( context, requestCode, intents, addMutabilityFlags(isMutable, flags), options); } @@ -52,8 +54,12 @@ public static PendingIntent getActivities( * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. */ - public static PendingIntent getActivities( - Context context, int requestCode, Intent[] intents, boolean isMutable, int flags) { + public static @NonNull PendingIntent getActivities( + @NonNull Context context, + int requestCode, + @NonNull @SuppressLint("ArrayReturn") Intent[] intents, + boolean isMutable, + int flags) { return PendingIntent.getActivities( context, requestCode, intents, addMutabilityFlags(isMutable, flags)); } @@ -64,8 +70,12 @@ public static PendingIntent getActivities( * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getActivity(Context, int, Intent, int)}. */ - public static PendingIntent getActivity( - Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + public static @NonNull PendingIntent getActivity( + @NonNull Context context, + int requestCode, + @NonNull Intent intent, + boolean isMutable, + int flags) { return PendingIntent.getActivity( context, requestCode, intent, addMutabilityFlags(isMutable, flags)); } @@ -76,13 +86,13 @@ public static PendingIntent getActivity( * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getActivity(Context, int, Intent, int, Bundle)}. */ - public static PendingIntent getActivity( - Context context, + public static @NonNull PendingIntent getActivity( + @NonNull Context context, int requestCode, - Intent intent, + @NonNull Intent intent, boolean isMutable, int flags, - Bundle options) { + @NonNull Bundle options) { return PendingIntent.getActivity( context, requestCode, intent, addMutabilityFlags(isMutable, flags), options); } @@ -93,8 +103,12 @@ public static PendingIntent getActivity( * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getBroadcast(Context, int, Intent, int)}. */ - public static PendingIntent getBroadcast( - Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + public static @NonNull PendingIntent getBroadcast( + @NonNull Context context, + int requestCode, + @NonNull Intent intent, + boolean isMutable, + int flags) { return PendingIntent.getBroadcast( context, requestCode, intent, addMutabilityFlags(isMutable, flags)); } @@ -106,8 +120,12 @@ public static PendingIntent getBroadcast( * PendingIntent#getForegroundService(Context, int, Intent, int)} . */ @RequiresApi(api = Build.VERSION_CODES.O) - public static PendingIntent getForegroundService( - Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + public static @NonNull PendingIntent getForegroundService( + @NonNull Context context, + int requestCode, + @NonNull Intent intent, + boolean isMutable, + int flags) { return PendingIntent.getForegroundService( context, requestCode, intent, addMutabilityFlags(isMutable, flags)); } @@ -118,8 +136,12 @@ public static PendingIntent getForegroundService( * flag. This method combines mutability flag when necessary. See {@link * PendingIntent#getService(Context, int, Intent, int)}. */ - public static PendingIntent getService( - Context context, int requestCode, Intent intent, boolean isMutable, int flags) { + public static @NonNull PendingIntent getService( + @NonNull Context context, + int requestCode, + @NonNull Intent intent, + boolean isMutable, + int flags) { return PendingIntent.getService( context, requestCode, intent, addMutabilityFlags(isMutable, flags)); } diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java index b99ec36..72c7471 100644 --- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java +++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java @@ -22,16 +22,16 @@ public class PendingIntentCompatTest { @Config(sdk = Build.VERSION_CODES.LOLLIPOP_MR1) @Test - public void getActivities_notMutableOnPreM() { + public void addMutabilityFlags_immutableOnPreM() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getActivity( context, requestCode, - intents, + intent, /* isMutable= */ false, PendingIntent.FLAG_UPDATE_CURRENT, options)); @@ -42,16 +42,16 @@ public void getActivities_notMutableOnPreM() { @Config(sdk = Build.VERSION_CODES.M) @Test - public void getActivities_notMutableOnMPlus() { + public void addMutabilityFlags_immutableOnMPlus() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getActivity( context, requestCode, - intents, + intent, /* isMutable= */ false, PendingIntent.FLAG_UPDATE_CURRENT, options)); @@ -63,17 +63,17 @@ public void getActivities_notMutableOnMPlus() { @Config(sdk = Build.VERSION_CODES.R) @Test - public void getActivities_notMutableOnPreS() { + public void addMutabilityFlags_mutableOnPreS() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getActivity( context, requestCode, - intents, - /* isMutable= */ false, + intent, + /* isMutable= */ true, PendingIntent.FLAG_UPDATE_CURRENT, options)); assertThat(shadow.isActivityIntent()).isTrue(); @@ -81,29 +81,29 @@ public void getActivities_notMutableOnPreS() { assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } - @Config(sdk = Build.VERSION_CODES.R) + @Config(sdk = Build.VERSION_CODES.S) @Test - public void getActivities_MutableOnPreS() { + public void addMutabilityFlags_mutableOnSPlus() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getActivity( context, requestCode, - intents, + intent, /* isMutable= */ true, PendingIntent.FLAG_UPDATE_CURRENT, options)); assertThat(shadow.isActivityIntent()).isTrue(); - assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } - @Config(sdk = Build.VERSION_CODES.R) @Test - public void getActivities_MutableOnSPlus() { + public void getActivities_withBundle() { int requestCode = 7465; Intent[] intents = new Intent[] {}; Bundle options = new Bundle(); @@ -113,18 +113,14 @@ public void getActivities_MutableOnSPlus() { context, requestCode, intents, - /* isMutable= */ true, + /* isMutable= */ false, PendingIntent.FLAG_UPDATE_CURRENT, options)); assertThat(shadow.isActivityIntent()).isTrue(); - assertThat(shadow.getFlags()) - .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } - @Config(sdk = Build.VERSION_CODES.R) @Test - public void getActivities_notMutableOnSPlus() { + public void getActivities() { int requestCode = 7465; Intent[] intents = new Intent[] {}; Bundle options = new Bundle(); @@ -135,47 +131,89 @@ public void getActivities_notMutableOnSPlus() { requestCode, intents, /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT)); + assertThat(shadow.isActivityIntent()).isTrue(); + } + + @Test + public void getActivity_withBundle() { + int requestCode = 7465; + Intent intent = new Intent(); + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivity( + context, + requestCode, + intent, + /* isMutable= */ false, PendingIntent.FLAG_UPDATE_CURRENT, options)); assertThat(shadow.isActivityIntent()).isTrue(); - assertThat(shadow.getFlags()) - .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } - @Config(sdk = Build.VERSION_CODES.R) + @Test + public void getActivity() { + int requestCode = 7465; + Intent intent = new Intent(); + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getActivity( + context, + requestCode, + intent, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT)); + assertThat(shadow.isActivityIntent()).isTrue(); + } + @Test public void getService() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getService( context, requestCode, - intents, + intent, /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); + PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.isService()).isTrue(); } - @Config(sdk = Build.VERSION_CODES.R) @Test public void getBroadcast() { int requestCode = 7465; - Intent[] intents = new Intent[] {}; + Intent intent = new Intent(); Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivities( + PendingIntentCompat.getBroadcast( context, requestCode, - intents, + intent, /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); + PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.isBroadcast()).isTrue(); } + + @Config(sdk = Build.VERSION_CODES.S) + @Test + public void getForegroundService() { + int requestCode = 7465; + Intent intent = new Intent(); + Bundle options = new Bundle(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getForegroundService( + context, + requestCode, + intent, + /* isMutable= */ false, + PendingIntent.FLAG_UPDATE_CURRENT)); + assertThat(shadow.isForegroundService()).isTrue(); + } } From 07d729e1ac45857f4feb9e44d2cbe01bae533913 Mon Sep 17 00:00:00 2001 From: Ada Date: Tue, 26 Jul 2022 09:51:38 +0800 Subject: [PATCH 6/7] Fix the problem that PendingIntentCompatTest can't run and provide a tidy PendingIntentCompat specific for this project --- GNSSLogger/app/build.gradle | 6 + .../gps/gnsslogger/PendingIntentCompat.java | 102 ------------ .../gnsslogger/PendingIntentCompatTest.java | 145 +----------------- 3 files changed, 14 insertions(+), 239 deletions(-) diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle index 3eedd6e..134c8e3 100644 --- a/GNSSLogger/app/build.gradle +++ b/GNSSLogger/app/build.gradle @@ -26,6 +26,12 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + + testOptions { + unitTests { + includeAndroidResources = true + } + } } dependencies { diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java index cd4c460..6ffba8f 100644 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java @@ -19,84 +19,15 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; -import android.annotation.SuppressLint; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; -import android.os.Bundle; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; /** Helper for accessing features in {@link PendingIntent}. */ public class PendingIntentCompat { - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. - */ - public static @NonNull PendingIntent getActivities( - @NonNull Context context, - int requestCode, - @NonNull @SuppressLint("ArrayReturn") Intent[] intents, - boolean isMutable, - int flags, - @NonNull Bundle options) { - return PendingIntent.getActivities( - context, requestCode, intents, addMutabilityFlags(isMutable, flags), options); - } - - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getActivities(Context, int, Intent[], int, Bundle)}. - */ - public static @NonNull PendingIntent getActivities( - @NonNull Context context, - int requestCode, - @NonNull @SuppressLint("ArrayReturn") Intent[] intents, - boolean isMutable, - int flags) { - return PendingIntent.getActivities( - context, requestCode, intents, addMutabilityFlags(isMutable, flags)); - } - - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getActivity(Context, int, Intent, int)}. - */ - public static @NonNull PendingIntent getActivity( - @NonNull Context context, - int requestCode, - @NonNull Intent intent, - boolean isMutable, - int flags) { - return PendingIntent.getActivity( - context, requestCode, intent, addMutabilityFlags(isMutable, flags)); - } - - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getActivity(Context, int, Intent, int, Bundle)}. - */ - public static @NonNull PendingIntent getActivity( - @NonNull Context context, - int requestCode, - @NonNull Intent intent, - boolean isMutable, - int flags, - @NonNull Bundle options) { - return PendingIntent.getActivity( - context, requestCode, intent, addMutabilityFlags(isMutable, flags), options); - } - /** * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform * versions. The caller provides the flag as combination of all the other values except mutability @@ -113,39 +44,6 @@ public class PendingIntentCompat { context, requestCode, intent, addMutabilityFlags(isMutable, flags)); } - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getForegroundService(Context, int, Intent, int)} . - */ - @RequiresApi(api = Build.VERSION_CODES.O) - public static @NonNull PendingIntent getForegroundService( - @NonNull Context context, - int requestCode, - @NonNull Intent intent, - boolean isMutable, - int flags) { - return PendingIntent.getForegroundService( - context, requestCode, intent, addMutabilityFlags(isMutable, flags)); - } - - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getService(Context, int, Intent, int)}. - */ - public static @NonNull PendingIntent getService( - @NonNull Context context, - int requestCode, - @NonNull Intent intent, - boolean isMutable, - int flags) { - return PendingIntent.getService( - context, requestCode, intent, addMutabilityFlags(isMutable, flags)); - } - private static int addMutabilityFlags(boolean isMutable, int flags) { if (isMutable) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java index 72c7471..a664beb 100644 --- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java +++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java @@ -20,27 +20,8 @@ public class PendingIntentCompatTest { private final Context context = ApplicationProvider.getApplicationContext(); - @Config(sdk = Build.VERSION_CODES.LOLLIPOP_MR1) - @Test - public void addMutabilityFlags_immutableOnPreM() { - int requestCode = 7465; - Intent intent = new Intent(); - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getActivity( - context, - requestCode, - intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); - assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); - } - - @Config(sdk = Build.VERSION_CODES.M) + /** Immutable is introduced in M, but the project's minimum support version is 24 */ + @Config(sdk = Build.VERSION_CODES.N) @Test public void addMutabilityFlags_immutableOnMPlus() { int requestCode = 7465; @@ -48,17 +29,14 @@ public void addMutabilityFlags_immutableOnMPlus() { Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivity( + PendingIntentCompat.getBroadcast( context, requestCode, intent, /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); + PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.getFlags()) .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } @Config(sdk = Build.VERSION_CODES.R) @@ -66,19 +44,15 @@ public void addMutabilityFlags_immutableOnMPlus() { public void addMutabilityFlags_mutableOnPreS() { int requestCode = 7465; Intent intent = new Intent(); - Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivity( + PendingIntentCompat.getBroadcast( context, requestCode, intent, /* isMutable= */ true, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); + PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); } @Config(sdk = Build.VERSION_CODES.S) @@ -86,102 +60,16 @@ public void addMutabilityFlags_mutableOnPreS() { public void addMutabilityFlags_mutableOnSPlus() { int requestCode = 7465; Intent intent = new Intent(); - Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( - PendingIntentCompat.getActivity( + PendingIntentCompat.getBroadcast( context, requestCode, intent, /* isMutable= */ true, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); + PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.getFlags()) .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); - assertThat(shadow.getRequestCode()).isEqualTo(requestCode); - } - - @Test - public void getActivities_withBundle() { - int requestCode = 7465; - Intent[] intents = new Intent[] {}; - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getActivities( - context, - requestCode, - intents, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); - } - - @Test - public void getActivities() { - int requestCode = 7465; - Intent[] intents = new Intent[] {}; - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getActivities( - context, - requestCode, - intents, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); - assertThat(shadow.isActivityIntent()).isTrue(); - } - - @Test - public void getActivity_withBundle() { - int requestCode = 7465; - Intent intent = new Intent(); - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getActivity( - context, - requestCode, - intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT, - options)); - assertThat(shadow.isActivityIntent()).isTrue(); - } - - @Test - public void getActivity() { - int requestCode = 7465; - Intent intent = new Intent(); - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getActivity( - context, - requestCode, - intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); - assertThat(shadow.isActivityIntent()).isTrue(); - } - - @Test - public void getService() { - int requestCode = 7465; - Intent intent = new Intent(); - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getService( - context, - requestCode, - intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); - assertThat(shadow.isService()).isTrue(); } @Test @@ -199,21 +87,4 @@ public void getBroadcast() { PendingIntent.FLAG_UPDATE_CURRENT)); assertThat(shadow.isBroadcast()).isTrue(); } - - @Config(sdk = Build.VERSION_CODES.S) - @Test - public void getForegroundService() { - int requestCode = 7465; - Intent intent = new Intent(); - Bundle options = new Bundle(); - ShadowPendingIntent shadow = - shadowOf( - PendingIntentCompat.getForegroundService( - context, - requestCode, - intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); - assertThat(shadow.isForegroundService()).isTrue(); - } } From b7d04e5bb3c5926f4e1eb807cbfb12bc4e6b2539 Mon Sep 17 00:00:00 2001 From: Ada Date: Fri, 29 Jul 2022 00:54:24 +0800 Subject: [PATCH 7/7] Convert PendingIntentCompat to Kotlin --- GNSSLogger/.idea/jarRepositories.xml | 20 ++++++ GNSSLogger/app/build.gradle | 12 +++- .../location/gps/gnsslogger/MainActivity.java | 5 +- .../gps/gnsslogger/PendingIntentCompat.java | 62 ------------------- .../gnsslogger/util/PendingIntentCompat.kt | 54 ++++++++++++++++ .../{ => util}/PendingIntentCompatTest.java | 59 +++++++++++++----- GNSSLogger/build.gradle | 9 +++ GNSSLogger/settings.gradle | 2 +- 8 files changed, 141 insertions(+), 82 deletions(-) create mode 100644 GNSSLogger/.idea/jarRepositories.xml delete mode 100644 GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java create mode 100644 GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt rename GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/{ => util}/PendingIntentCompatTest.java (57%) diff --git a/GNSSLogger/.idea/jarRepositories.xml b/GNSSLogger/.idea/jarRepositories.xml new file mode 100644 index 0000000..0a1b94d --- /dev/null +++ b/GNSSLogger/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/GNSSLogger/app/build.gradle b/GNSSLogger/app/build.gradle index 134c8e3..936cb46 100644 --- a/GNSSLogger/app/build.gradle +++ b/GNSSLogger/app/build.gradle @@ -2,6 +2,7 @@ plugins { id 'com.android.application' id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' } +apply plugin: 'kotlin-android' android { compileSdk 32 @@ -44,11 +45,16 @@ dependencies { implementation files('libs/achartengine-1.2.0.jar') implementation("com.google.guava:guava:31.1-android") implementation 'com.google.android.material:material:1.6.1' - implementation 'androidx.test:core:1.4.0' + implementation "androidx.core:core:1.8.0" + testImplementation 'androidx.test:core:1.4.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.8.1' + testImplementation "com.google.truth:truth:1.1.3" androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test.ext:junit:1.1.3' - testImplementation "com.google.truth:truth:1.1.3" - implementation "androidx.core:core:1.8.0" + implementation "androidx.core:core-ktx:+" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() } \ No newline at end of file diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java index a500751..5e7131a 100755 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/MainActivity.java @@ -41,6 +41,7 @@ import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.viewpager.widget.ViewPager; +import com.google.android.apps.location.gps.gnsslogger.util.PendingIntentCompat; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; @@ -144,8 +145,8 @@ protected PendingIntent createActivityDetectionPendingIntent() { /* context= */ this, /* requestCode= */ 0, intent, - /* isMutable= */ true, - PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ true); } private synchronized void buildGoogleApiClient() { diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java deleted file mode 100644 index 6ffba8f..0000000 --- a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompat.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.apps.location.gps.gnsslogger; - -import static android.app.PendingIntent.FLAG_IMMUTABLE; -import static android.app.PendingIntent.FLAG_MUTABLE; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import androidx.annotation.NonNull; - -/** Helper for accessing features in {@link PendingIntent}. */ -public class PendingIntentCompat { - - /** - * Retrieves a {@link PendingIntent} with mandatory mutability flag set on supported platform - * versions. The caller provides the flag as combination of all the other values except mutability - * flag. This method combines mutability flag when necessary. See {@link - * PendingIntent#getBroadcast(Context, int, Intent, int)}. - */ - public static @NonNull PendingIntent getBroadcast( - @NonNull Context context, - int requestCode, - @NonNull Intent intent, - boolean isMutable, - int flags) { - return PendingIntent.getBroadcast( - context, requestCode, intent, addMutabilityFlags(isMutable, flags)); - } - - private static int addMutabilityFlags(boolean isMutable, int flags) { - if (isMutable) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - flags |= FLAG_MUTABLE; - } - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - flags |= FLAG_IMMUTABLE; - } - } - - return flags; - } - - private PendingIntentCompat() {} -} diff --git a/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt new file mode 100644 index 0000000..b8da594 --- /dev/null +++ b/GNSSLogger/app/src/main/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompat.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.apps.location.gps.gnsslogger.util + +import android.content.Intent +import android.app.PendingIntent +import android.content.Context +import com.google.android.apps.location.gps.gnsslogger.util.PendingIntentCompat +import android.os.Build + +/** Helper for accessing features in [PendingIntent]. */ +object PendingIntentCompat { + /** + * Retrieves a [PendingIntent] with mandatory mutability flag set on supported platform + * versions. The caller provides the flag as combination of all the other values except mutability + * flag. This method combines mutability flag when necessary. See [ ][PendingIntent.getBroadcast]. + */ + @JvmStatic + fun getBroadcast( + context: Context, + requestCode: Int, + intent: Intent, + flags: Int, + isMutable: Boolean): PendingIntent { + return PendingIntent.getBroadcast( + context, requestCode, intent, addMutabilityFlags(isMutable, flags)) + } + + private fun addMutabilityFlags(isMutable: Boolean, flags: Int): Int { + var flags = flags + if (isMutable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + flags = flags or PendingIntent.FLAG_MUTABLE + } + } else { + // Minimum support SDK is 24. + flags = flags or PendingIntent.FLAG_IMMUTABLE + } + return flags + } +} \ No newline at end of file diff --git a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java similarity index 57% rename from GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java rename to GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java index a664beb..f44d1d2 100644 --- a/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/PendingIntentCompatTest.java +++ b/GNSSLogger/app/src/test/java/com/google/android/apps/location/gps/gnsslogger/util/PendingIntentCompatTest.java @@ -1,4 +1,4 @@ -package com.google.android.apps.location.gps.gnsslogger; +package com.google.android.apps.location.gps.gnsslogger.util; import static com.google.common.truth.Truth.assertThat; import static org.robolectric.Shadows.shadowOf; @@ -7,7 +7,6 @@ import android.content.Context; import android.content.Intent; import android.os.Build; -import android.os.Bundle; import androidx.test.core.app.ApplicationProvider; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,20 +25,19 @@ public class PendingIntentCompatTest { public void addMutabilityFlags_immutableOnMPlus() { int requestCode = 7465; Intent intent = new Intent(); - Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getBroadcast( context, requestCode, intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ false)); assertThat(shadow.getFlags()) .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); } - @Config(sdk = Build.VERSION_CODES.R) + @Config(maxSdk = Build.VERSION_CODES.R) @Test public void addMutabilityFlags_mutableOnPreS() { int requestCode = 7465; @@ -50,12 +48,29 @@ public void addMutabilityFlags_mutableOnPreS() { context, requestCode, intent, - /* isMutable= */ true, - PendingIntent.FLAG_UPDATE_CURRENT)); + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ true)); assertThat(shadow.getFlags()).isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT); } - @Config(sdk = Build.VERSION_CODES.S) + @Config(maxSdk = Build.VERSION_CODES.R) + @Test + public void addMutabilityFlags_immutableOnPreS() { + int requestCode = 7465; + Intent intent = new Intent(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getBroadcast( + context, + requestCode, + intent, + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ false)); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } + + @Config(minSdk = Build.VERSION_CODES.S) @Test public void addMutabilityFlags_mutableOnSPlus() { int requestCode = 7465; @@ -66,25 +81,41 @@ public void addMutabilityFlags_mutableOnSPlus() { context, requestCode, intent, - /* isMutable= */ true, - PendingIntent.FLAG_UPDATE_CURRENT)); + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ true)); assertThat(shadow.getFlags()) .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); } + @Config(minSdk = Build.VERSION_CODES.S) + @Test + public void addMutabilityFlags_immutableOnSPlus() { + int requestCode = 7465; + Intent intent = new Intent(); + ShadowPendingIntent shadow = + shadowOf( + PendingIntentCompat.getBroadcast( + context, + requestCode, + intent, + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ false)); + assertThat(shadow.getFlags()) + .isEqualTo(PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + } + @Test public void getBroadcast() { int requestCode = 7465; Intent intent = new Intent(); - Bundle options = new Bundle(); ShadowPendingIntent shadow = shadowOf( PendingIntentCompat.getBroadcast( context, requestCode, intent, - /* isMutable= */ false, - PendingIntent.FLAG_UPDATE_CURRENT)); + PendingIntent.FLAG_UPDATE_CURRENT, + /* isMutable= */ false)); assertThat(shadow.isBroadcast()).isTrue(); } } diff --git a/GNSSLogger/build.gradle b/GNSSLogger/build.gradle index 41052eb..bb78f47 100644 --- a/GNSSLogger/build.gradle +++ b/GNSSLogger/build.gradle @@ -1,4 +1,13 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + ext.kotlin_version = '1.7.20-Beta' + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} plugins { id 'com.android.application' version '7.2.1' apply false id 'com.android.library' version '7.2.1' apply false diff --git a/GNSSLogger/settings.gradle b/GNSSLogger/settings.gradle index 0e73733..58d7621 100644 --- a/GNSSLogger/settings.gradle +++ b/GNSSLogger/settings.gradle @@ -6,7 +6,7 @@ pluginManagement { } } dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { google() mavenCentral()