diff options
16 files changed, 83 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt index 9935e6d35221..70b0d8a5294a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9882,7 +9882,7 @@ package android.content { method public void notifyChange(@NonNull android.net.Uri, @Nullable android.database.ContentObserver); method @Deprecated public void notifyChange(@NonNull android.net.Uri, @Nullable android.database.ContentObserver, boolean); method public void notifyChange(@NonNull android.net.Uri, @Nullable android.database.ContentObserver, int); - method public void notifyChange(@NonNull Iterable<android.net.Uri>, @Nullable android.database.ContentObserver, int); + method public void notifyChange(@NonNull java.util.Collection<android.net.Uri>, @Nullable android.database.ContentObserver, int); method @Nullable public final android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException; method @Nullable public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(@NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException; method @Nullable public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException; @@ -12972,11 +12972,11 @@ package android.database { method @Deprecated public final void dispatchChange(boolean); method public final void dispatchChange(boolean, @Nullable android.net.Uri); method public final void dispatchChange(boolean, @Nullable android.net.Uri, int); - method public final void dispatchChange(boolean, @NonNull Iterable<android.net.Uri>, int); + method public final void dispatchChange(boolean, @NonNull java.util.Collection<android.net.Uri>, int); method public void onChange(boolean); method public void onChange(boolean, @Nullable android.net.Uri); method public void onChange(boolean, @Nullable android.net.Uri, int); - method public void onChange(boolean, @NonNull Iterable<android.net.Uri>, int); + method public void onChange(boolean, @NonNull java.util.Collection<android.net.Uri>, int); } public interface CrossProcessCursor extends android.database.Cursor { diff --git a/api/removed.txt b/api/removed.txt index fb6d57694c78..8537b21eb438 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -69,6 +69,10 @@ package android.app.usage { package android.content { + public abstract class ContentResolver { + method @Deprecated public void notifyChange(@NonNull Iterable<android.net.Uri>, @Nullable android.database.ContentObserver, int); + } + public abstract class Context { method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); method public abstract java.io.File getSharedPreferencesPath(String); 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); } } diff --git a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java index c307e648752d..328429c6f96e 100644 --- a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java +++ b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java @@ -39,6 +39,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -194,8 +195,8 @@ abstract class AbstractCrossUserContentResolverTest { } @Override - public void onChange(boolean selfChange, Uri uri, int userId) { - if (mExpectedUri.equals(uri) && mExpectedUserId == userId) { + public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) { + if (uris.contains(mExpectedUri) && mExpectedUserId == userId) { mLatch.countDown(); } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 03674648d1e4..2200b22b8b27 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -43,6 +43,7 @@ import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; @@ -74,8 +75,8 @@ public final class ClockManager { private final ContentObserver mContentObserver = new ContentObserver(mMainHandler) { @Override - public void onChange(boolean selfChange, Uri uri, int userId) { - super.onChange(selfChange, uri, userId); + public void onChange(boolean selfChange, Collection<Uri> uris, + int flags, int userId) { if (Objects.equals(userId, mCurrentUserObservable.getCurrentUser().getValue())) { reload(); diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt index 989b7cf2423b..e5d36f942ac8 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt @@ -127,7 +127,7 @@ class ControlsControllerImpl @Inject constructor ( internal val settingObserver = object : ContentObserver(null) { override fun onChange( selfChange: Boolean, - uris: MutableIterable<Uri>, + uris: Collection<Uri>, flags: Int, userId: Int ) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index c28a719b9826..700a8611c8bd 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -49,6 +49,7 @@ import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.wakelock.WakeLock; import java.io.PrintWriter; +import java.util.Collection; import java.util.List; import java.util.function.Consumer; @@ -261,7 +262,7 @@ public class DozeSensors { private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) { @Override - public void onChange(boolean selfChange, Iterable<Uri> uris, int flags, int userId) { + public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) { if (userId != ActivityManager.getCurrentUser()) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index 30db37c4f128..f31f8eb0b20d 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -43,6 +43,7 @@ import com.google.android.collect.Sets; import org.json.JSONException; import org.json.JSONObject; +import java.util.Collection; import java.util.Map; import java.util.Set; @@ -101,7 +102,7 @@ public class ThemeOverlayController extends SystemUI { new ContentObserver(mBgHandler) { @Override - public void onChange(boolean selfChange, Iterable<Uri> uris, int flags, + public void onChange(boolean selfChange, Collection<Uri> uris, int flags, int userId) { if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId); if (ActivityManager.getCurrentUser() == userId) { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index b2a5f5bee543..2452218226bb 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -262,7 +262,8 @@ public class TunerServiceImpl extends TunerService { } @Override - public void onChange(boolean selfChange, Iterable<Uri> uris, int flags, int userId) { + public void onChange(boolean selfChange, java.util.Collection<Uri> uris, + int flags, int userId) { if (userId == ActivityManager.getCurrentUser()) { for (Uri u : uris) { reloadSetting(u); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index d3ff912ea327..21d300aba1b9 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -288,6 +288,7 @@ import java.lang.ref.WeakReference; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -680,7 +681,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void onChange(boolean selfChange, Iterable<Uri> uris, int flags, + public void onChange(boolean selfChange, Collection<Uri> uris, int flags, @UserIdInt int userId) { for (Uri uri : uris) { if (mFontScaleUri.equals(uri)) { diff --git a/test-mock/src/android/test/mock/MockContentResolver.java b/test-mock/src/android/test/mock/MockContentResolver.java index 8283019a10ec..8f4bcccb0cba 100644 --- a/test-mock/src/android/test/mock/MockContentResolver.java +++ b/test-mock/src/android/test/mock/MockContentResolver.java @@ -25,6 +25,7 @@ import android.content.IContentProvider; import android.database.ContentObserver; import android.net.Uri; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -172,7 +173,7 @@ public class MockContentResolver extends ContentResolver { * from observers elsewhere in the system. */ @Override - public void notifyChange(@NonNull Iterable<Uri> uris, @Nullable ContentObserver observer, + public void notifyChange(@NonNull Collection<Uri> uris, @Nullable ContentObserver observer, @NotifyFlags int flags) { } } |