From d3a2031750a0be8f09132cf9b3f8c8a70546658d Mon Sep 17 00:00:00 2001 From: Goooler Date: Sat, 31 Aug 2024 14:50:16 +0800 Subject: [PATCH] Pass context for calling IconCompat.toIcon `androidx.core.graphics.drawable.IconCompat.toIcon()` is deprecated, we should avoid calling it in core lib to prevent the exception thrown like: ``` java.lang.IllegalArgumentException: Context is required to resolve the file uri of the icon: content://com.google.android.samples.socialite/icon/1 at androidx.core.graphics.drawable.IconCompat$Api23Impl.toIcon(IconCompat.java:1297) at androidx.core.graphics.drawable.IconCompat.toIcon(IconCompat.java:529) at androidx.core.graphics.drawable.IconCompat.toIcon(IconCompat.java:517) at androidx.core.app.Person$Api28Impl.toAndroidPerson(Person.java:427) at androidx.core.app.Person.toAndroidPerson(Person.java:152) at androidx.core.app.NotificationCompatBuilder.(NotificationCompatBuilder.java:263) at androidx.core.app.NotificationCompat$Builder.build(NotificationCompat.java:2531) at com.google.android.samples.socialite.repository.NotificationHelper.showNotification(NotificationHelper.kt:274) at com.google.android.samples.socialite.repository.NotificationHelper.showNotification$default(NotificationHelper.kt:159) at com.google.android.samples.socialite.repository.ChatRepository$sendMessage$2.invokeSuspend(ChatRepository.kt:92) ``` Test: ./gradlew :core:core:check Change-Id: I9c3874ae91efbb382693f679cadad62a9cba4a83 --- core/core/api/current.txt | 6 ++-- core/core/api/restricted_current.txt | 9 +++-- .../androidx/core/app/NotificationCompat.java | 35 +++++++++++++++---- .../core/app/NotificationCompatBuilder.java | 8 ++--- .../main/java/androidx/core/app/Person.java | 23 +++++++++--- .../androidx/core/app/RemoteActionCompat.java | 20 +++++++++-- 6 files changed, 79 insertions(+), 22 deletions(-) diff --git a/core/core/api/current.txt b/core/core/api/current.txt index 2c49d7ea8ce12..d67c4c9f31e77 100644 --- a/core/core/api/current.txt +++ b/core/core/api/current.txt @@ -511,7 +511,8 @@ package androidx.core.app { method public android.app.PendingIntent? getIntent(); method public String? getShortcutId(); method public boolean isNotificationSuppressed(); - method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?); + method public static android.app.Notification.BubbleMetadata? toPlatform(android.content.Context, androidx.core.app.NotificationCompat.BubbleMetadata?); + method @Deprecated public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?); } public static final class NotificationCompat.BubbleMetadata.Builder { @@ -941,7 +942,8 @@ package androidx.core.app { method public void setEnabled(boolean); method public void setShouldShowIcon(boolean); method public boolean shouldShowIcon(); - method @RequiresApi(26) public android.app.RemoteAction toRemoteAction(); + method @Deprecated @RequiresApi(26) public android.app.RemoteAction toRemoteAction(); + method @RequiresApi(26) public android.app.RemoteAction toRemoteAction(android.content.Context); } public final class RemoteInput { diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt index 4f16f2dd681db..e5b0a868ccb82 100644 --- a/core/core/api/restricted_current.txt +++ b/core/core/api/restricted_current.txt @@ -570,7 +570,8 @@ package androidx.core.app { method public String? getShortcutId(); method public boolean isNotificationSuppressed(); method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setFlags(int); - method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?); + method public static android.app.Notification.BubbleMetadata? toPlatform(android.content.Context, androidx.core.app.NotificationCompat.BubbleMetadata?); + method @Deprecated public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?); } public static final class NotificationCompat.BubbleMetadata.Builder { @@ -1010,7 +1011,8 @@ package androidx.core.app { method public boolean isBot(); method public boolean isImportant(); method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String resolveToLegacyUri(); - method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.app.Person toAndroidPerson(); + method @Deprecated @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.app.Person toAndroidPerson(); + method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.app.Person toAndroidPerson(android.content.Context); method public androidx.core.app.Person.Builder toBuilder(); method public android.os.Bundle toBundle(); method @RequiresApi(22) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.os.PersistableBundle toPersistableBundle(); @@ -1049,7 +1051,8 @@ package androidx.core.app { method public void setEnabled(boolean); method public void setShouldShowIcon(boolean); method public boolean shouldShowIcon(); - method @RequiresApi(26) public android.app.RemoteAction toRemoteAction(); + method @Deprecated @RequiresApi(26) public android.app.RemoteAction toRemoteAction(); + method @RequiresApi(26) public android.app.RemoteAction toRemoteAction(android.content.Context); field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(4) public android.app.PendingIntent mActionIntent; field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(3) public CharSequence mContentDescription; field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(5) public boolean mEnabled; diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompat.java b/core/core/src/main/java/androidx/core/app/NotificationCompat.java index d1317abff7536..3535ca2133ce6 100644 --- a/core/core/src/main/java/androidx/core/app/NotificationCompat.java +++ b/core/core/src/main/java/androidx/core/app/NotificationCompat.java @@ -6811,7 +6811,7 @@ public NotificationCompat.Builder extend(@NonNull NotificationCompat.Builder bui for (Action action : mActions) { if (Build.VERSION.SDK_INT >= 20) { parcelables.add( - WearableExtender.getActionFromActionCompat(action)); + WearableExtender.getActionFromActionCompat(builder.mContext, action)); } else { parcelables.add(NotificationCompatJellybean.getBundleForAction(action)); } @@ -6865,12 +6865,12 @@ public NotificationCompat.Builder extend(@NonNull NotificationCompat.Builder bui } @RequiresApi(20) - private static Notification.Action getActionFromActionCompat(Action actionCompat) { + private static Notification.Action getActionFromActionCompat(Context context, Action actionCompat) { Notification.Action.Builder actionBuilder; if (Build.VERSION.SDK_INT >= 23) { IconCompat iconCompat = actionCompat.getIconCompat(); actionBuilder = Api23Impl.createBuilder( - iconCompat == null ? null : iconCompat.toIcon(), actionCompat.getTitle(), + iconCompat == null ? null : iconCompat.toIcon(context), actionCompat.getTitle(), actionCompat.getActionIntent()); } else { IconCompat icon = actionCompat.getIconCompat(); @@ -8501,16 +8501,35 @@ public void setFlags(int flags) { * @param compatMetadata the NotificationCompat.BubbleMetadata to convert * @return a {@link Notification.BubbleMetadata} containing the same data if compatMetadata * is non-null, otherwise null. + * + * @deprecated use {@link #toPlatform(Context, BubbleMetadata)} instead. + */ + @Deprecated + public static @Nullable android.app.Notification.BubbleMetadata toPlatform( + @Nullable BubbleMetadata compatMetadata) { + //noinspection DataFlowIssue + return toPlatform(null, compatMetadata); + } + + /** + * Converts a {@link NotificationCompat.BubbleMetadata} to a platform-level + * {@link Notification.BubbleMetadata}. + * + * @param context A {@link Context} that will be used to get icon from the bubbleMetadata. + * @param compatMetadata the NotificationCompat.BubbleMetadata to convert + * @return a {@link Notification.BubbleMetadata} containing the same data if compatMetadata + * is non-null, otherwise null. */ public static @Nullable android.app.Notification.BubbleMetadata toPlatform( + @NonNull Context context, @Nullable BubbleMetadata compatMetadata) { if (compatMetadata == null) { return null; } if (Build.VERSION.SDK_INT >= 30) { - return Api30Impl.toPlatform(compatMetadata); + return Api30Impl.toPlatform(context, compatMetadata); } else if (Build.VERSION.SDK_INT == 29) { - return Api29Impl.toPlatform(compatMetadata); + return Api29Impl.toPlatform(context, compatMetadata); } return null; } @@ -8786,6 +8805,7 @@ private Api29Impl() { */ @RequiresApi(29) @Nullable static android.app.Notification.BubbleMetadata toPlatform( + @NonNull Context context, @Nullable BubbleMetadata compatMetadata) { if (compatMetadata == null) { return null; @@ -8797,7 +8817,7 @@ private Api29Impl() { android.app.Notification.BubbleMetadata.Builder platformMetadataBuilder = new android.app.Notification.BubbleMetadata.Builder() - .setIcon(compatMetadata.getIcon().toIcon()) + .setIcon(compatMetadata.getIcon().toIcon(context)) .setIntent(compatMetadata.getIntent()) .setDeleteIntent(compatMetadata.getDeleteIntent()) .setAutoExpandBubble(compatMetadata.getAutoExpandBubble()) @@ -8869,6 +8889,7 @@ private Api30Impl() { */ @RequiresApi(30) @Nullable static android.app.Notification.BubbleMetadata toPlatform( + @NonNull Context context, @Nullable BubbleMetadata compatMetadata) { if (compatMetadata == null) { return null; @@ -8881,7 +8902,7 @@ private Api30Impl() { } else { platformMetadataBuilder = new android.app.Notification.BubbleMetadata.Builder( - compatMetadata.getIntent(), compatMetadata.getIcon().toIcon()); + compatMetadata.getIntent(), compatMetadata.getIcon().toIcon(context)); } platformMetadataBuilder .setDeleteIntent(compatMetadata.getDeleteIntent()) diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java b/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java index 8dbcd2329df25..0e34e16b74386 100644 --- a/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java +++ b/core/core/src/main/java/androidx/core/app/NotificationCompatBuilder.java @@ -120,11 +120,11 @@ class NotificationCompatBuilder implements NotificationBuilderWithBuilderAccesso ((NotificationCompat.CallStyle) b.mStyle).getActionsListWithSystemActions(); // Adds the actions to the builder in the proper order. for (NotificationCompat.Action action : actionsList) { - addAction(action); + addAction(mContext, action); } } else { for (NotificationCompat.Action action : b.mActions) { - addAction(action); + addAction(mContext, action); } } @@ -366,13 +366,13 @@ public Notification build() { return n; } - private void addAction(NotificationCompat.Action action) { + private void addAction(Context context, NotificationCompat.Action action) { if (Build.VERSION.SDK_INT >= 20) { Notification.Action.Builder actionBuilder; IconCompat iconCompat = action.getIconCompat(); if (Build.VERSION.SDK_INT >= 23) { actionBuilder = Api23Impl.createBuilder( - iconCompat != null ? iconCompat.toIcon() : null, action.getTitle(), + iconCompat != null ? iconCompat.toIcon(context) : null, action.getTitle(), action.getActionIntent()); } else { actionBuilder = Api20Impl.createBuilder( diff --git a/core/core/src/main/java/androidx/core/app/Person.java b/core/core/src/main/java/androidx/core/app/Person.java index 441de1b8e0b2a..799be87c3b459 100644 --- a/core/core/src/main/java/androidx/core/app/Person.java +++ b/core/core/src/main/java/androidx/core/app/Person.java @@ -18,6 +18,7 @@ import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX; +import android.content.Context; import android.os.Bundle; import android.os.PersistableBundle; @@ -143,12 +144,27 @@ public Builder toBuilder() { /** * Converts this compat {@link Person} to the base Android framework {@link android.app.Person}. * + * @deprecated Use {@link #toAndroidPerson(Context)} instead. */ @RestrictTo(LIBRARY_GROUP_PREFIX) @NonNull @RequiresApi(28) + @Deprecated public android.app.Person toAndroidPerson() { - return Api28Impl.toAndroidPerson(this); + //noinspection DataFlowIssue + return toAndroidPerson(null); + } + + /** + * Converts this compat {@link Person} to the base Android framework {@link android.app.Person}. + * + * @param context A {@link Context} that will be used to get icon from the person. + */ + @RestrictTo(LIBRARY_GROUP_PREFIX) + @NonNull + @RequiresApi(28) + public android.app.Person toAndroidPerson(@NonNull Context context) { + return Api28Impl.toAndroidPerson(context, this); } /** @@ -415,11 +431,10 @@ static Person fromAndroidPerson(android.app.Person person) { .build(); } - @SuppressWarnings("deprecation") - static android.app.Person toAndroidPerson(Person person) { + static android.app.Person toAndroidPerson(Context context, Person person) { return new android.app.Person.Builder() .setName(person.getName()) - .setIcon((person.getIcon() != null) ? person.getIcon().toIcon() : null) + .setIcon((person.getIcon() != null) ? person.getIcon().toIcon(context) : null) .setUri(person.getUri()) .setKey(person.getKey()) .setBot(person.isBot()) diff --git a/core/core/src/main/java/androidx/core/app/RemoteActionCompat.java b/core/core/src/main/java/androidx/core/app/RemoteActionCompat.java index 120350c2af991..a6e29d623ac1a 100644 --- a/core/core/src/main/java/androidx/core/app/RemoteActionCompat.java +++ b/core/core/src/main/java/androidx/core/app/RemoteActionCompat.java @@ -21,6 +21,7 @@ import android.annotation.SuppressLint; import android.app.PendingIntent; import android.app.RemoteAction; +import android.content.Context; import android.graphics.drawable.Icon; import android.os.Build; @@ -189,12 +190,27 @@ public boolean shouldShowIcon() { * Convert this compat object to {@link RemoteAction} object. * * @return {@link RemoteAction} object + * + * @deprecated Use {@link #toRemoteAction(Context)} instead. */ - @SuppressWarnings("deprecation") @RequiresApi(26) @NonNull + @Deprecated public RemoteAction toRemoteAction() { - RemoteAction action = Api26Impl.createRemoteAction(mIcon.toIcon(), mTitle, + //noinspection DataFlowIssue + return toRemoteAction(null); + } + + /** + * Convert this compat object to {@link RemoteAction} object. + * + * @param context A {@link Context} that will be used to get icon from mIcon. + * @return {@link RemoteAction} object + */ + @RequiresApi(26) + @NonNull + public RemoteAction toRemoteAction(@NonNull Context context) { + RemoteAction action = Api26Impl.createRemoteAction(mIcon.toIcon(context), mTitle, mContentDescription, mActionIntent); Api26Impl.setEnabled(action, isEnabled()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {