summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2020-03-09 15:49:01 -0600
committerJeff Sharkey <jsharkey@android.com>2020-03-10 16:36:21 -0600
commit8b0cff710816999fddd33d3591bc52c87600c095 (patch)
tree463ec67d993b5f6eb45ea24ad024a76368510255 /core/java
parentf46b9c9656a28732d12efee205fbf4bb2acf2b87 (diff)
Give hidden API behavior to legacy apps.
Starting in R, there is a new public API overload that delivers a flags argument. Some apps may be relying on a previous hidden API that delivered a userId argument, and this change is used to control delivery of the new flags argument in its place. There are dozens of these hidden API users are in the system UID, either in the system process or the Settings app, so we hard-code giving them the legacy behavior, since refactoring would be messy between internal and AOSP branches. Also adjust incoming and outgoing method signatures to use slightly more flexible Collection<Uri>, which has handy methods like contains() and isEmpty(). Bug: 150939131 Test: atest --test-mapping packages/providers/MediaProvider Test: atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyManagerTest Exempt-From-Owner-Approval: trivial refactoring Change-Id: If6a77449e19215cf1c60d4217e62fc04b0959bfc
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/ContentResolver.java12
-rw-r--r--core/java/android/database/ContentObserver.java45
-rw-r--r--core/java/android/database/CursorToBulkCursorAdaptor.java8
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java3
-rw-r--r--core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java3
-rw-r--r--core/java/com/android/internal/util/NotificationMessagingUtil.java5
6 files changed, 59 insertions, 17 deletions
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 911ffa06ed38..31e1fc824ed2 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -83,6 +83,7 @@ import java.io.OutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Random;
@@ -2670,6 +2671,15 @@ public abstract class ContentResolver implements ContentInterface {
ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
}
+ /** @removed */
+ @Deprecated
+ public void notifyChange(@NonNull Iterable<Uri> uris, @Nullable ContentObserver observer,
+ @NotifyFlags int flags) {
+ final Collection<Uri> asCollection = new ArrayList<>();
+ uris.forEach(asCollection::add);
+ notifyChange(asCollection, observer, flags);
+ }
+
/**
* Notify registered observers that several rows have been updated.
* <p>
@@ -2694,7 +2704,7 @@ public abstract class ContentResolver implements ContentInterface {
* @param flags Flags such as {@link #NOTIFY_SYNC_TO_NETWORK} or
* {@link #NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS}.
*/
- public void notifyChange(@NonNull Iterable<Uri> uris, @Nullable ContentObserver observer,
+ public void notifyChange(@NonNull Collection<Uri> uris, @Nullable ContentObserver observer,
@NotifyFlags int flags) {
Objects.requireNonNull(uris, "uris");
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
index ede264d042ce..578d53b17bf9 100644
--- a/core/java/android/database/ContentObserver.java
+++ b/core/java/android/database/ContentObserver.java
@@ -19,6 +19,9 @@ package android.database;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver.NotifyFlags;
import android.net.Uri;
@@ -26,12 +29,26 @@ import android.os.Handler;
import android.os.UserHandle;
import java.util.Arrays;
+import java.util.Collection;
/**
* Receives call backs for changes to content.
* Must be implemented by objects which are added to a {@link ContentObservable}.
*/
public abstract class ContentObserver {
+ /**
+ * Starting in {@link android.os.Build.VERSION_CODES#R}, there is a new
+ * public API overload {@link #onChange(boolean, Uri, int)} that delivers a
+ * {@code int flags} argument.
+ * <p>
+ * Some apps may be relying on a previous hidden API that delivered a
+ * {@code int userId} argument, and this change is used to control delivery
+ * of the new {@code int flags} argument in its place.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q)
+ private static final long ADD_CONTENT_OBSERVER_FLAGS = 150939131L;
+
private final Object mLock = new Object();
private Transport mTransport; // guarded by mLock
@@ -164,16 +181,26 @@ public abstract class ContentObserver {
* @param uris The Uris of the changed content.
* @param flags Flags indicating details about this change.
*/
- public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris, @NotifyFlags int flags) {
+ public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
+ @NotifyFlags int flags) {
for (Uri uri : uris) {
onChange(selfChange, uri, flags);
}
}
/** @hide */
- public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris, @NotifyFlags int flags,
- @UserIdInt int userId) {
- onChange(selfChange, uris, flags);
+ public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
+ @NotifyFlags int flags, @UserIdInt int userId) {
+ // There are dozens of people relying on the hidden API inside the
+ // system UID, so hard-code the old behavior for all of them; for
+ // everyone else we gate based on a specific change
+ if (!CompatChanges.isChangeEnabled(ADD_CONTENT_OBSERVER_FLAGS)
+ || android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
+ // Deliver userId through argument to preserve hidden API behavior
+ onChange(selfChange, uris, userId);
+ } else {
+ onChange(selfChange, uris, flags);
+ }
}
/**
@@ -186,7 +213,7 @@ public abstract class ContentObserver {
*
* @deprecated Callers should migrate towards using a richer overload that
* provides more details about the change, such as
- * {@link #dispatchChange(boolean, Iterable, int)}.
+ * {@link #dispatchChange(boolean, Collection, int)}.
*/
@Deprecated
public final void dispatchChange(boolean selfChange) {
@@ -206,7 +233,7 @@ public abstract class ContentObserver {
* @param uri The Uri of the changed content.
*/
public final void dispatchChange(boolean selfChange, @Nullable Uri uri) {
- dispatchChange(selfChange, Arrays.asList(uri), 0, UserHandle.getCallingUserId());
+ dispatchChange(selfChange, uri, 0);
}
/**
@@ -224,7 +251,7 @@ public abstract class ContentObserver {
*/
public final void dispatchChange(boolean selfChange, @Nullable Uri uri,
@NotifyFlags int flags) {
- dispatchChange(selfChange, Arrays.asList(uri), flags, UserHandle.getCallingUserId());
+ dispatchChange(selfChange, Arrays.asList(uri), flags);
}
/**
@@ -240,13 +267,13 @@ public abstract class ContentObserver {
* @param uris The Uri of the changed content.
* @param flags Flags indicating details about this change.
*/
- public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ public final void dispatchChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags) {
dispatchChange(selfChange, uris, flags, UserHandle.getCallingUserId());
}
/** @hide */
- public final void dispatchChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ public final void dispatchChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags, @UserIdInt int userId) {
if (mHandler == null) {
onChange(selfChange, uris, flags, userId);
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 1855dd254ad4..ce86807ebf7a 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -20,10 +20,12 @@ import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ContentResolver.NotifyFlags;
import android.net.Uri;
-import android.os.*;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
import java.util.ArrayList;
-
+import java.util.Collection;
/**
* Wraps a BulkCursor around an existing Cursor making it remotable.
@@ -81,7 +83,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
}
@Override
- public void onChange(boolean selfChange, @NonNull Iterable<Uri> uris,
+ public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
@NotifyFlags int flags, @UserIdInt int userId) {
// Since we deliver changes from the most-specific to least-specific
// overloads, we only need to redirect from the most-specific local
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 5cdcab029877..54ea57a6cae4 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -56,6 +56,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -133,7 +134,7 @@ public class AccessibilityShortcutController {
// Keep track of state of shortcut settings
final ContentObserver co = new ContentObserver(handler) {
@Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
+ public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) {
if (userId == mUserId) {
onSettingsChanged();
}
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
index f8c0d9e4a27e..fdcc8a8c9cbf 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
@@ -29,6 +29,7 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Matcher;
@@ -99,7 +100,7 @@ public class KernelCpuThreadReaderSettingsObserver extends ContentObserver {
}
@Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
+ public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) {
updateReader();
}
diff --git a/core/java/com/android/internal/util/NotificationMessagingUtil.java b/core/java/com/android/internal/util/NotificationMessagingUtil.java
index bf796cddd89e..28994fd52126 100644
--- a/core/java/com/android/internal/util/NotificationMessagingUtil.java
+++ b/core/java/com/android/internal/util/NotificationMessagingUtil.java
@@ -28,6 +28,7 @@ import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
+import java.util.Collection;
import java.util.Objects;
/**
@@ -77,8 +78,8 @@ public class NotificationMessagingUtil {
private final ContentObserver mSmsContentObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- if (Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING).equals(uri)) {
+ public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) {
+ if (uris.contains(Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING))) {
cacheDefaultSmsApp(userId);
}
}