Loading core/java/android/content/ContentProvider.java +46 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.os.ICancellationSignal; import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -463,6 +464,23 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } } @Override public boolean refresh(String callingPkg, Uri uri, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return false; } final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.refresh(uri, args, CancellationSignal.fromTransport(cancellationSignal)); } finally { setCallingPackage(original); } } private void enforceFilePermission(String callingPkg, Uri uri, String mode, IBinder callerToken) throws FileNotFoundException, SecurityException { if (mode != null && mode.indexOf('w') != -1) { Loading Loading @@ -1092,6 +1110,34 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return url; } /** * Implement this to support refresh of content identified by {@code uri}. By default, this * method returns false; providers who wish to implement this should return true to signal the * client that the provider has tried refreshing with its own implementation. * <p> * This allows clients to request an explicit refresh of content identified by {@code uri}. * <p> * Client code should only invoke this method when there is a strong indication (such as a user * initiated pull to refresh gesture) that the content is stale. * <p> * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} * notifications when content changes. * * @param uri The Uri identifying the data to refresh. * @param args Additional options from the client. The definitions of these are specific to the * content provider being called. * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if * none. For example, if you called refresh on a particular uri, you should call * {@link CancellationSignal#throwIfCanceled()} to check whether the client has * canceled the refresh request. * @return true if the provider actually tried refreshing. * @hide */ public boolean refresh(Uri uri, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { return false; } /** * @hide * Implementation when a caller has performed an insert on the content Loading core/java/android/content/ContentProviderClient.java +24 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,30 @@ public class ContentProviderClient implements AutoCloseable { } } /** @hide */ public boolean refresh(Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) throws RemoteException { Preconditions.checkNotNull(url, "url"); beforeRemote(); try { ICancellationSignal remoteCancellationSignal = null; if (cancellationSignal != null) { cancellationSignal.throwIfCanceled(); remoteCancellationSignal = mContentProvider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } return mContentProvider.refresh(mPackageName, url, args, remoteCancellationSignal); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); } throw e; } finally { afterRemote(); } } /** See {@link ContentProvider#insert ContentProvider.insert} */ public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues) throws RemoteException { Loading core/java/android/content/ContentProviderNative.java +37 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,20 @@ abstract public class ContentProviderNative extends Binder implements IContentPr Uri.writeToParcel(reply, out); return true; } case REFRESH_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); String callingPkg = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); Bundle args = data.readBundle(); ICancellationSignal signal = ICancellationSignal.Stub.asInterface( data.readStrongBinder()); boolean out = refresh(callingPkg, url, args, signal); reply.writeNoException(); reply.writeInt(out ? 0 : -1); return true; } } } catch (Exception e) { DatabaseUtils.writeExceptionToParcel(reply, e); Loading Loading @@ -761,5 +775,28 @@ final class ContentProviderProxy implements IContentProvider } } public boolean refresh(String callingPkg, Uri url, Bundle args, ICancellationSignal signal) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); data.writeString(callingPkg); url.writeToParcel(data, 0); data.writeBundle(args); data.writeStrongBinder(signal != null ? signal.asBinder() : null); mRemote.transact(IContentProvider.REFRESH_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); int success = reply.readInt(); return (success == 0); } finally { data.recycle(); reply.recycle(); } } private IBinder mRemote; } core/java/android/content/ContentResolver.java +57 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,15 @@ public abstract class ContentResolver { */ public static final String EXTRA_SIZE = "android.content.extra.SIZE"; /** * An extra boolean describing whether a particular provider supports refresh * or not. If a provider supports refresh, it should include this key in its * returned Cursor as part of its query call. * * @hide */ public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; /** * This is the Android platform's base MIME type for a content: URI * containing a Cursor of a single item. Applications should use this Loading Loading @@ -663,6 +672,54 @@ public abstract class ContentResolver { } } /** * Implement this to support refresh of content identified by {@code uri}. By default, this * method returns false; providers who wish to implement this should return true to signal the * client that the provider has tried refreshing with its own implementation. * <p> * This allows clients to request an explicit refresh of content identified by {@code uri}. * <p> * Client code should only invoke this method when there is a strong indication (such as a user * initiated pull to refresh gesture) that the content is stale. * <p> * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} * notifications when content changes. * * @param uri The Uri identifying the data to refresh. * @param args Additional options from the client. The definitions of these are specific to the * content provider being called. * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if * none. For example, if you called refresh on a particular uri, you should call * {@link CancellationSignal#throwIfCanceled()} to check whether the client has * canceled the refresh request. * @return true if the provider actually tried refreshing. * @hide */ public final boolean refresh(@NonNull Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(url, "url"); IContentProvider provider = acquireProvider(url); if (provider == null) { return false; } try { ICancellationSignal remoteCancellationSignal = null; if (cancellationSignal != null) { cancellationSignal.throwIfCanceled(); remoteCancellationSignal = provider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } return provider.refresh(mPackageName, url, args, remoteCancellationSignal); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. return false; } finally { releaseProvider(provider); } } /** * Open a stream on to the content associated with a content URI. If there * is no data associated with the URI, FileNotFoundException is thrown. Loading core/java/android/content/IContentProvider.java +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ public interface IContentProvider extends IInterface { public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException; public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException; public boolean refresh(String callingPkg, Uri url, @Nullable Bundle args, ICancellationSignal cancellationSignal) throws RemoteException; // Data interchange. public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException; public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType, Loading @@ -88,4 +91,5 @@ public interface IContentProvider extends IInterface { static final int CREATE_CANCELATION_SIGNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 23; static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24; static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25; static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26; } Loading
core/java/android/content/ContentProvider.java +46 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.os.ICancellationSignal; import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -463,6 +464,23 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } } @Override public boolean refresh(String callingPkg, Uri uri, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return false; } final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.refresh(uri, args, CancellationSignal.fromTransport(cancellationSignal)); } finally { setCallingPackage(original); } } private void enforceFilePermission(String callingPkg, Uri uri, String mode, IBinder callerToken) throws FileNotFoundException, SecurityException { if (mode != null && mode.indexOf('w') != -1) { Loading Loading @@ -1092,6 +1110,34 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return url; } /** * Implement this to support refresh of content identified by {@code uri}. By default, this * method returns false; providers who wish to implement this should return true to signal the * client that the provider has tried refreshing with its own implementation. * <p> * This allows clients to request an explicit refresh of content identified by {@code uri}. * <p> * Client code should only invoke this method when there is a strong indication (such as a user * initiated pull to refresh gesture) that the content is stale. * <p> * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} * notifications when content changes. * * @param uri The Uri identifying the data to refresh. * @param args Additional options from the client. The definitions of these are specific to the * content provider being called. * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if * none. For example, if you called refresh on a particular uri, you should call * {@link CancellationSignal#throwIfCanceled()} to check whether the client has * canceled the refresh request. * @return true if the provider actually tried refreshing. * @hide */ public boolean refresh(Uri uri, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { return false; } /** * @hide * Implementation when a caller has performed an insert on the content Loading
core/java/android/content/ContentProviderClient.java +24 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,30 @@ public class ContentProviderClient implements AutoCloseable { } } /** @hide */ public boolean refresh(Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) throws RemoteException { Preconditions.checkNotNull(url, "url"); beforeRemote(); try { ICancellationSignal remoteCancellationSignal = null; if (cancellationSignal != null) { cancellationSignal.throwIfCanceled(); remoteCancellationSignal = mContentProvider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } return mContentProvider.refresh(mPackageName, url, args, remoteCancellationSignal); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); } throw e; } finally { afterRemote(); } } /** See {@link ContentProvider#insert ContentProvider.insert} */ public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues) throws RemoteException { Loading
core/java/android/content/ContentProviderNative.java +37 −0 Original line number Diff line number Diff line Loading @@ -355,6 +355,20 @@ abstract public class ContentProviderNative extends Binder implements IContentPr Uri.writeToParcel(reply, out); return true; } case REFRESH_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); String callingPkg = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); Bundle args = data.readBundle(); ICancellationSignal signal = ICancellationSignal.Stub.asInterface( data.readStrongBinder()); boolean out = refresh(callingPkg, url, args, signal); reply.writeNoException(); reply.writeInt(out ? 0 : -1); return true; } } } catch (Exception e) { DatabaseUtils.writeExceptionToParcel(reply, e); Loading Loading @@ -761,5 +775,28 @@ final class ContentProviderProxy implements IContentProvider } } public boolean refresh(String callingPkg, Uri url, Bundle args, ICancellationSignal signal) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); data.writeString(callingPkg); url.writeToParcel(data, 0); data.writeBundle(args); data.writeStrongBinder(signal != null ? signal.asBinder() : null); mRemote.transact(IContentProvider.REFRESH_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); int success = reply.readInt(); return (success == 0); } finally { data.recycle(); reply.recycle(); } } private IBinder mRemote; }
core/java/android/content/ContentResolver.java +57 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,15 @@ public abstract class ContentResolver { */ public static final String EXTRA_SIZE = "android.content.extra.SIZE"; /** * An extra boolean describing whether a particular provider supports refresh * or not. If a provider supports refresh, it should include this key in its * returned Cursor as part of its query call. * * @hide */ public static final String EXTRA_REFRESH_SUPPORTED = "android.content.extra.REFRESH_SUPPORTED"; /** * This is the Android platform's base MIME type for a content: URI * containing a Cursor of a single item. Applications should use this Loading Loading @@ -663,6 +672,54 @@ public abstract class ContentResolver { } } /** * Implement this to support refresh of content identified by {@code uri}. By default, this * method returns false; providers who wish to implement this should return true to signal the * client that the provider has tried refreshing with its own implementation. * <p> * This allows clients to request an explicit refresh of content identified by {@code uri}. * <p> * Client code should only invoke this method when there is a strong indication (such as a user * initiated pull to refresh gesture) that the content is stale. * <p> * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} * notifications when content changes. * * @param uri The Uri identifying the data to refresh. * @param args Additional options from the client. The definitions of these are specific to the * content provider being called. * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if * none. For example, if you called refresh on a particular uri, you should call * {@link CancellationSignal#throwIfCanceled()} to check whether the client has * canceled the refresh request. * @return true if the provider actually tried refreshing. * @hide */ public final boolean refresh(@NonNull Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(url, "url"); IContentProvider provider = acquireProvider(url); if (provider == null) { return false; } try { ICancellationSignal remoteCancellationSignal = null; if (cancellationSignal != null) { cancellationSignal.throwIfCanceled(); remoteCancellationSignal = provider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } return provider.refresh(mPackageName, url, args, remoteCancellationSignal); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. return false; } finally { releaseProvider(provider); } } /** * Open a stream on to the content associated with a content URI. If there * is no data associated with the URI, FileNotFoundException is thrown. Loading
core/java/android/content/IContentProvider.java +4 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ public interface IContentProvider extends IInterface { public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException; public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException; public boolean refresh(String callingPkg, Uri url, @Nullable Bundle args, ICancellationSignal cancellationSignal) throws RemoteException; // Data interchange. public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException; public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType, Loading @@ -88,4 +91,5 @@ public interface IContentProvider extends IInterface { static final int CREATE_CANCELATION_SIGNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 23; static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24; static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25; static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26; }