Loading core/java/android/content/ContentResolver.java +65 −36 Original line number Original line Diff line number Diff line Loading @@ -500,6 +500,7 @@ public abstract class ContentResolver { public ContentResolver(Context context) { public ContentResolver(Context context) { mContext = context != null ? context : ActivityThread.currentApplication(); mContext = context != null ? context : ActivityThread.currentApplication(); mPackageName = mContext.getOpPackageName(); mPackageName = mContext.getOpPackageName(); mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; } } /** @hide */ /** @hide */ Loading Loading @@ -1868,13 +1869,18 @@ public abstract class ContentResolver { /** /** * Register an observer class that gets callbacks when data identified by a * Register an observer class that gets callbacks when data identified by a * given content URI changes. * given content URI changes. * * <p> * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * for a whole class of content. * notifications must be backed by a valid {@link ContentProvider}. * @param notifyForDescendants When false, the observer will be notified whenever a * * change occurs to the exact URI specified by <code>uri</code> or to one of the * @param uri The URI to watch for changes. This can be a specific row URI, * URI's ancestors in the path hierarchy. When true, the observer will also be notified * or a base URI for a whole class of content. * whenever a change occurs to the URI's descendants in the path hierarchy. * @param notifyForDescendants When false, the observer will be notified * whenever a change occurs to the exact URI specified by * <code>uri</code> or to one of the URI's ancestors in the path * hierarchy. When true, the observer will also be notified * whenever a change occurs to the URI's descendants in the path * hierarchy. * @param observer The object that receives callbacks when changes occur. * @param observer The object that receives callbacks when changes occur. * @see #unregisterContentObserver * @see #unregisterContentObserver */ */ Loading @@ -1894,7 +1900,7 @@ public abstract class ContentResolver { ContentObserver observer, @UserIdInt int userHandle) { ContentObserver observer, @UserIdInt int userHandle) { try { try { getContentService().registerContentObserver(uri, notifyForDescendents, getContentService().registerContentObserver(uri, notifyForDescendents, observer.getContentObserver(), userHandle); observer.getContentObserver(), userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading @@ -1918,16 +1924,22 @@ public abstract class ContentResolver { } } /** /** * Notify registered observers that a row was updated and attempt to sync changes * Notify registered observers that a row was updated and attempt to sync * to the network. * changes to the network. * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. */ */ public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) { public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) { notifyChange(uri, observer, true /* sync to network */); notifyChange(uri, observer, true /* sync to network */); Loading @@ -1935,17 +1947,25 @@ public abstract class ContentResolver { /** /** * Notify registered observers that a row was updated. * Notify registered observers that a row was updated. * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * If syncToNetwork is true, this will attempt to schedule a local sync using the sync * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * adapter that's registered for the authority of the provided uri. No account will be * <p> * passed to the sync adapter, so all matching accounts will be synchronized. * If syncToNetwork is true, this will attempt to schedule a local sync * using the sync adapter that's registered for the authority of the * provided uri. No account will be passed to the sync adapter, so all * matching accounts will be synchronized. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}. * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}. * @see #requestSync(android.accounts.Account, String, android.os.Bundle) * @see #requestSync(android.accounts.Account, String, android.os.Bundle) */ */ Loading @@ -1961,17 +1981,25 @@ public abstract class ContentResolver { /** /** * Notify registered observers that a row was updated. * Notify registered observers that a row was updated. * To register, call {@link #registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * If syncToNetwork is true, this will attempt to schedule a local sync using the sync * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * adapter that's registered for the authority of the provided uri. No account will be * <p> * passed to the sync adapter, so all matching accounts will be synchronized. * If syncToNetwork is true, this will attempt to schedule a local sync * using the sync adapter that's registered for the authority of the * provided uri. No account will be passed to the sync adapter, so all * matching accounts will be synchronized. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}. * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}. * @see #requestSync(android.accounts.Account, String, android.os.Bundle) * @see #requestSync(android.accounts.Account, String, android.os.Bundle) */ */ Loading @@ -1997,7 +2025,7 @@ public abstract class ContentResolver { uri, observer == null ? null : observer.getContentObserver(), uri, observer == null ? null : observer.getContentObserver(), observer != null && observer.deliverSelfNotifications(), observer != null && observer.deliverSelfNotifications(), syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0, syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0, userHandle); userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading @@ -2013,7 +2041,7 @@ public abstract class ContentResolver { getContentService().notifyChange( getContentService().notifyChange( uri, observer == null ? null : observer.getContentObserver(), uri, observer == null ? null : observer.getContentObserver(), observer != null && observer.deliverSelfNotifications(), flags, observer != null && observer.deliverSelfNotifications(), flags, userHandle); userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading Loading @@ -2932,6 +2960,7 @@ public abstract class ContentResolver { private final Context mContext; private final Context mContext; final String mPackageName; final String mPackageName; final int mTargetSdkVersion; private static final String TAG = "ContentResolver"; private static final String TAG = "ContentResolver"; Loading core/java/android/content/IContentService.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,7 @@ interface IContentService { * USER_CURRENT are properly handled. * USER_CURRENT are properly handled. */ */ void registerContentObserver(in Uri uri, boolean notifyForDescendants, void registerContentObserver(in Uri uri, boolean notifyForDescendants, IContentObserver observer, int userHandle); IContentObserver observer, int userHandle, int targetSdkVersion); /** /** * Notify observers of a particular user's view of the provider. * Notify observers of a particular user's view of the provider. Loading @@ -53,7 +53,7 @@ interface IContentService { */ */ void notifyChange(in Uri uri, IContentObserver observer, void notifyChange(in Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, int flags, boolean observerWantsSelfNotifications, int flags, int userHandle); int userHandle, int targetSdkVersion); void requestSync(in Account account, String authority, in Bundle extras); void requestSync(in Account account, String authority, in Bundle extras); /** /** Loading services/core/java/com/android/server/am/ActivityManagerService.java +1 −4 Original line number Original line Diff line number Diff line Loading @@ -10708,10 +10708,7 @@ public class ActivityManagerService extends IActivityManager.Stub } catch (RemoteException ignored) { } catch (RemoteException ignored) { } } if (cpi == null) { if (cpi == null) { // TODO: make this an outright failure in a future platform release; return "Failed to find provider " + authority + " for user " + userId; // until then anonymous content notifications are unprotected //return "Failed to find provider " + authority + " for user " + userId; return null; } } ProcessRecord r = null; ProcessRecord r = null; Loading services/core/java/com/android/server/content/ContentService.java +28 −9 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.database.IContentObserver; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteException; import android.net.Uri; import android.net.Uri; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.FactoryTest; import android.os.FactoryTest; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -287,7 +288,7 @@ public final class ContentService extends IContentService.Stub { */ */ @Override @Override public void registerContentObserver(Uri uri, boolean notifyForDescendants, public void registerContentObserver(Uri uri, boolean notifyForDescendants, IContentObserver observer, int userHandle) { IContentObserver observer, int userHandle, int targetSdkVersion) { if (observer == null || uri == null) { if (observer == null || uri == null) { throw new IllegalArgumentException("You must pass a valid uri and observer"); throw new IllegalArgumentException("You must pass a valid uri and observer"); } } Loading @@ -301,9 +302,18 @@ public final class ContentService extends IContentService.Stub { final String msg = LocalServices.getService(ActivityManagerInternal.class) final String msg = LocalServices.getService(ActivityManagerInternal.class) .checkContentProviderAccess(uri.getAuthority(), userHandle); .checkContentProviderAccess(uri.getAuthority(), userHandle); if (msg != null) { if (msg != null) { if (targetSdkVersion >= Build.VERSION_CODES.O) { throw new SecurityException(msg); } else { if (msg.startsWith("Failed to find provider")) { // Sigh, we need to quietly let apps targeting older API // levels notify on non-existent providers. } else { Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); return; return; } } } } synchronized (mRootNode) { synchronized (mRootNode) { mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode, mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode, Loading @@ -316,7 +326,7 @@ public final class ContentService extends IContentService.Stub { public void registerContentObserver(Uri uri, boolean notifyForDescendants, public void registerContentObserver(Uri uri, boolean notifyForDescendants, IContentObserver observer) { IContentObserver observer) { registerContentObserver(uri, notifyForDescendants, observer, registerContentObserver(uri, notifyForDescendants, observer, UserHandle.getCallingUserId()); UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT); } } @Override @Override Loading @@ -340,8 +350,8 @@ public final class ContentService extends IContentService.Stub { */ */ @Override @Override public void notifyChange(Uri uri, IContentObserver observer, public void notifyChange(Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, int flags, boolean observerWantsSelfNotifications, int flags, int userHandle, int userHandle) { int targetSdkVersion) { if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle + " from observer " + observer + ", flags " + Integer.toHexString(flags)); + " from observer " + observer + ", flags " + Integer.toHexString(flags)); Loading @@ -359,9 +369,18 @@ public final class ContentService extends IContentService.Stub { final String msg = LocalServices.getService(ActivityManagerInternal.class) final String msg = LocalServices.getService(ActivityManagerInternal.class) .checkContentProviderAccess(uri.getAuthority(), userHandle); .checkContentProviderAccess(uri.getAuthority(), userHandle); if (msg != null) { if (msg != null) { if (targetSdkVersion >= Build.VERSION_CODES.O) { throw new SecurityException(msg); } else { if (msg.startsWith("Failed to find provider")) { // Sigh, we need to quietly let apps targeting older API // levels notify on non-existent providers. } else { Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); return; return; } } } } // This makes it so that future permission checks will be in the context of this // This makes it so that future permission checks will be in the context of this // process rather than the caller's process. We will restore this before returning. // process rather than the caller's process. We will restore this before returning. Loading Loading @@ -427,7 +446,7 @@ public final class ContentService extends IContentService.Stub { boolean observerWantsSelfNotifications, boolean syncToNetwork) { boolean observerWantsSelfNotifications, boolean syncToNetwork) { notifyChange(uri, observer, observerWantsSelfNotifications, notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0, syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0, UserHandle.getCallingUserId()); UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT); } } /** /** Loading Loading
core/java/android/content/ContentResolver.java +65 −36 Original line number Original line Diff line number Diff line Loading @@ -500,6 +500,7 @@ public abstract class ContentResolver { public ContentResolver(Context context) { public ContentResolver(Context context) { mContext = context != null ? context : ActivityThread.currentApplication(); mContext = context != null ? context : ActivityThread.currentApplication(); mPackageName = mContext.getOpPackageName(); mPackageName = mContext.getOpPackageName(); mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; } } /** @hide */ /** @hide */ Loading Loading @@ -1868,13 +1869,18 @@ public abstract class ContentResolver { /** /** * Register an observer class that gets callbacks when data identified by a * Register an observer class that gets callbacks when data identified by a * given content URI changes. * given content URI changes. * * <p> * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * for a whole class of content. * notifications must be backed by a valid {@link ContentProvider}. * @param notifyForDescendants When false, the observer will be notified whenever a * * change occurs to the exact URI specified by <code>uri</code> or to one of the * @param uri The URI to watch for changes. This can be a specific row URI, * URI's ancestors in the path hierarchy. When true, the observer will also be notified * or a base URI for a whole class of content. * whenever a change occurs to the URI's descendants in the path hierarchy. * @param notifyForDescendants When false, the observer will be notified * whenever a change occurs to the exact URI specified by * <code>uri</code> or to one of the URI's ancestors in the path * hierarchy. When true, the observer will also be notified * whenever a change occurs to the URI's descendants in the path * hierarchy. * @param observer The object that receives callbacks when changes occur. * @param observer The object that receives callbacks when changes occur. * @see #unregisterContentObserver * @see #unregisterContentObserver */ */ Loading @@ -1894,7 +1900,7 @@ public abstract class ContentResolver { ContentObserver observer, @UserIdInt int userHandle) { ContentObserver observer, @UserIdInt int userHandle) { try { try { getContentService().registerContentObserver(uri, notifyForDescendents, getContentService().registerContentObserver(uri, notifyForDescendents, observer.getContentObserver(), userHandle); observer.getContentObserver(), userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading @@ -1918,16 +1924,22 @@ public abstract class ContentResolver { } } /** /** * Notify registered observers that a row was updated and attempt to sync changes * Notify registered observers that a row was updated and attempt to sync * to the network. * changes to the network. * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. */ */ public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) { public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) { notifyChange(uri, observer, true /* sync to network */); notifyChange(uri, observer, true /* sync to network */); Loading @@ -1935,17 +1947,25 @@ public abstract class ContentResolver { /** /** * Notify registered observers that a row was updated. * Notify registered observers that a row was updated. * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * If syncToNetwork is true, this will attempt to schedule a local sync using the sync * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * adapter that's registered for the authority of the provided uri. No account will be * <p> * passed to the sync adapter, so all matching accounts will be synchronized. * If syncToNetwork is true, this will attempt to schedule a local sync * using the sync adapter that's registered for the authority of the * provided uri. No account will be passed to the sync adapter, so all * matching accounts will be synchronized. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}. * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}. * @see #requestSync(android.accounts.Account, String, android.os.Bundle) * @see #requestSync(android.accounts.Account, String, android.os.Bundle) */ */ Loading @@ -1961,17 +1981,25 @@ public abstract class ContentResolver { /** /** * Notify registered observers that a row was updated. * Notify registered observers that a row was updated. * To register, call {@link #registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver) registerContentObserver()}. * <p> * By default, CursorAdapter objects will get this notification. * To observe events sent through this call, use * If syncToNetwork is true, this will attempt to schedule a local sync using the sync * {@link #registerContentObserver(Uri, boolean, ContentObserver)}. * adapter that's registered for the authority of the provided uri. No account will be * <p> * passed to the sync adapter, so all matching accounts will be synchronized. * If syncToNetwork is true, this will attempt to schedule a local sync * using the sync adapter that's registered for the authority of the * provided uri. No account will be passed to the sync adapter, so all * matching accounts will be synchronized. * <p> * Starting in {@link android.os.Build.VERSION_CODES#O}, all content * notifications must be backed by a valid {@link ContentProvider}. * * * @param uri The uri of the content that was changed. * @param uri The uri of the content that was changed. * @param observer The observer that originated the change, may be <code>null</null>. * @param observer The observer that originated the change, may be * The observer that originated the change will only receive the notification if it * <code>null</null>. The observer that originated the change * has requested to receive self-change notifications by implementing * will only receive the notification if it has requested to * {@link ContentObserver#deliverSelfNotifications()} to return true. * receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return * true. * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}. * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}. * @see #requestSync(android.accounts.Account, String, android.os.Bundle) * @see #requestSync(android.accounts.Account, String, android.os.Bundle) */ */ Loading @@ -1997,7 +2025,7 @@ public abstract class ContentResolver { uri, observer == null ? null : observer.getContentObserver(), uri, observer == null ? null : observer.getContentObserver(), observer != null && observer.deliverSelfNotifications(), observer != null && observer.deliverSelfNotifications(), syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0, syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0, userHandle); userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading @@ -2013,7 +2041,7 @@ public abstract class ContentResolver { getContentService().notifyChange( getContentService().notifyChange( uri, observer == null ? null : observer.getContentObserver(), uri, observer == null ? null : observer.getContentObserver(), observer != null && observer.deliverSelfNotifications(), flags, observer != null && observer.deliverSelfNotifications(), flags, userHandle); userHandle, mTargetSdkVersion); } catch (RemoteException e) { } catch (RemoteException e) { } } } } Loading Loading @@ -2932,6 +2960,7 @@ public abstract class ContentResolver { private final Context mContext; private final Context mContext; final String mPackageName; final String mPackageName; final int mTargetSdkVersion; private static final String TAG = "ContentResolver"; private static final String TAG = "ContentResolver"; Loading
core/java/android/content/IContentService.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,7 @@ interface IContentService { * USER_CURRENT are properly handled. * USER_CURRENT are properly handled. */ */ void registerContentObserver(in Uri uri, boolean notifyForDescendants, void registerContentObserver(in Uri uri, boolean notifyForDescendants, IContentObserver observer, int userHandle); IContentObserver observer, int userHandle, int targetSdkVersion); /** /** * Notify observers of a particular user's view of the provider. * Notify observers of a particular user's view of the provider. Loading @@ -53,7 +53,7 @@ interface IContentService { */ */ void notifyChange(in Uri uri, IContentObserver observer, void notifyChange(in Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, int flags, boolean observerWantsSelfNotifications, int flags, int userHandle); int userHandle, int targetSdkVersion); void requestSync(in Account account, String authority, in Bundle extras); void requestSync(in Account account, String authority, in Bundle extras); /** /** Loading
services/core/java/com/android/server/am/ActivityManagerService.java +1 −4 Original line number Original line Diff line number Diff line Loading @@ -10708,10 +10708,7 @@ public class ActivityManagerService extends IActivityManager.Stub } catch (RemoteException ignored) { } catch (RemoteException ignored) { } } if (cpi == null) { if (cpi == null) { // TODO: make this an outright failure in a future platform release; return "Failed to find provider " + authority + " for user " + userId; // until then anonymous content notifications are unprotected //return "Failed to find provider " + authority + " for user " + userId; return null; } } ProcessRecord r = null; ProcessRecord r = null; Loading
services/core/java/com/android/server/content/ContentService.java +28 −9 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.database.IContentObserver; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteException; import android.net.Uri; import android.net.Uri; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Bundle; import android.os.FactoryTest; import android.os.FactoryTest; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -287,7 +288,7 @@ public final class ContentService extends IContentService.Stub { */ */ @Override @Override public void registerContentObserver(Uri uri, boolean notifyForDescendants, public void registerContentObserver(Uri uri, boolean notifyForDescendants, IContentObserver observer, int userHandle) { IContentObserver observer, int userHandle, int targetSdkVersion) { if (observer == null || uri == null) { if (observer == null || uri == null) { throw new IllegalArgumentException("You must pass a valid uri and observer"); throw new IllegalArgumentException("You must pass a valid uri and observer"); } } Loading @@ -301,9 +302,18 @@ public final class ContentService extends IContentService.Stub { final String msg = LocalServices.getService(ActivityManagerInternal.class) final String msg = LocalServices.getService(ActivityManagerInternal.class) .checkContentProviderAccess(uri.getAuthority(), userHandle); .checkContentProviderAccess(uri.getAuthority(), userHandle); if (msg != null) { if (msg != null) { if (targetSdkVersion >= Build.VERSION_CODES.O) { throw new SecurityException(msg); } else { if (msg.startsWith("Failed to find provider")) { // Sigh, we need to quietly let apps targeting older API // levels notify on non-existent providers. } else { Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); return; return; } } } } synchronized (mRootNode) { synchronized (mRootNode) { mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode, mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode, Loading @@ -316,7 +326,7 @@ public final class ContentService extends IContentService.Stub { public void registerContentObserver(Uri uri, boolean notifyForDescendants, public void registerContentObserver(Uri uri, boolean notifyForDescendants, IContentObserver observer) { IContentObserver observer) { registerContentObserver(uri, notifyForDescendants, observer, registerContentObserver(uri, notifyForDescendants, observer, UserHandle.getCallingUserId()); UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT); } } @Override @Override Loading @@ -340,8 +350,8 @@ public final class ContentService extends IContentService.Stub { */ */ @Override @Override public void notifyChange(Uri uri, IContentObserver observer, public void notifyChange(Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, int flags, boolean observerWantsSelfNotifications, int flags, int userHandle, int userHandle) { int targetSdkVersion) { if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle + " from observer " + observer + ", flags " + Integer.toHexString(flags)); + " from observer " + observer + ", flags " + Integer.toHexString(flags)); Loading @@ -359,9 +369,18 @@ public final class ContentService extends IContentService.Stub { final String msg = LocalServices.getService(ActivityManagerInternal.class) final String msg = LocalServices.getService(ActivityManagerInternal.class) .checkContentProviderAccess(uri.getAuthority(), userHandle); .checkContentProviderAccess(uri.getAuthority(), userHandle); if (msg != null) { if (msg != null) { if (targetSdkVersion >= Build.VERSION_CODES.O) { throw new SecurityException(msg); } else { if (msg.startsWith("Failed to find provider")) { // Sigh, we need to quietly let apps targeting older API // levels notify on non-existent providers. } else { Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); return; return; } } } } // This makes it so that future permission checks will be in the context of this // This makes it so that future permission checks will be in the context of this // process rather than the caller's process. We will restore this before returning. // process rather than the caller's process. We will restore this before returning. Loading Loading @@ -427,7 +446,7 @@ public final class ContentService extends IContentService.Stub { boolean observerWantsSelfNotifications, boolean syncToNetwork) { boolean observerWantsSelfNotifications, boolean syncToNetwork) { notifyChange(uri, observer, observerWantsSelfNotifications, notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0, syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0, UserHandle.getCallingUserId()); UserHandle.getCallingUserId(), Build.VERSION_CODES.CUR_DEVELOPMENT); } } /** /** Loading