use of android.os.ICancellationSignal in project platform_frameworks_base by android.
the class ContentResolver method query.
/**
* Query the given URI, returning a {@link Cursor} over the result set
* with optional support for cancellation.
* <p>
* For best performance, the caller should follow these guidelines:
* <ul>
* <li>Provide an explicit projection, to prevent
* reading data from storage that aren't going to be used.</li>
* <li>Use question mark parameter markers such as 'phone=?' instead of
* explicit values in the {@code selection} parameter, so that queries
* that differ only by those values will be recognized as the same
* for caching purposes.</li>
* </ul>
* </p>
*
* @param uri The URI, using the content:// scheme, for the content to
* retrieve.
* @param projection A list of which columns to return. Passing null will
* return all columns, which is inefficient.
* @param selection A filter declaring which rows to return, formatted as an
* SQL WHERE clause (excluding the WHERE itself). Passing null will
* return all rows for the given URI.
* @param selectionArgs You may include ?s in selection, which will be
* replaced by the values from selectionArgs, in the order that they
* appear in the selection. The values will be bound as Strings.
* @param sortOrder How to order the rows, formatted as an SQL ORDER BY
* clause (excluding the ORDER BY itself). Passing null will use the
* default sort order, which may be unordered.
* @param cancellationSignal A signal to cancel the operation in progress, or null if none.
* If the operation is canceled, then {@link OperationCanceledException} will be thrown
* when the query is executed.
* @return A Cursor object, which is positioned before the first entry, or null
* @see Cursor
*/
@Nullable
public final Cursor query(@RequiresPermission.Read @NonNull final Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal) {
Preconditions.checkNotNull(uri, "uri");
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
return null;
}
IContentProvider stableProvider = null;
Cursor qCursor = null;
try {
long startTime = SystemClock.uptimeMillis();
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = unstableProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
qCursor = unstableProvider.query(mPackageName, uri, projection, selection, selectionArgs, sortOrder, remoteCancellationSignal);
} catch (DeadObjectException e) {
// The remote process has died... but we only hold an unstable
// reference though, so we might recover!!! Let's try!!!!
// This is exciting!!1!!1!!!!1
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
return null;
}
qCursor = stableProvider.query(mPackageName, uri, projection, selection, selectionArgs, sortOrder, remoteCancellationSignal);
}
if (qCursor == null) {
return null;
}
// Force query execution. Might fail and throw a runtime exception here.
qCursor.getCount();
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
// Wrap the cursor object into CursorWrapperInner object.
final IContentProvider provider = (stableProvider != null) ? stableProvider : acquireProvider(uri);
final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
stableProvider = null;
qCursor = null;
return wrapper;
} catch (RemoteException e) {
// Manager will kill this process shortly anyway.
return null;
} finally {
if (qCursor != null) {
qCursor.close();
}
if (cancellationSignal != null) {
cancellationSignal.setRemote(null);
}
if (unstableProvider != null) {
releaseUnstableProvider(unstableProvider);
}
if (stableProvider != null) {
releaseProvider(stableProvider);
}
}
}
use of android.os.ICancellationSignal in project platform_frameworks_base by android.
the class ContentResolver method openAssetFileDescriptor.
/**
* Open a raw file descriptor to access data under a URI. This
* interacts with the underlying {@link ContentProvider#openAssetFile}
* method of the provider associated with the given URI, to retrieve any file stored there.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
* <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5>
* <p>
* A Uri object can be used to reference a resource in an APK file. The
* Uri should be one of the following formats:
* <ul>
* <li><code>android.resource://package_name/id_number</code><br/>
* <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
* For example <code>com.example.myapp</code><br/>
* <code>id_number</code> is the int form of the ID.<br/>
* The easiest way to construct this form is
* <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre>
* </li>
* <li><code>android.resource://package_name/type/name</code><br/>
* <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
* For example <code>com.example.myapp</code><br/>
* <code>type</code> is the string form of the resource type. For example, <code>raw</code>
* or <code>drawable</code>.
* <code>name</code> is the string form of the resource name. That is, whatever the file
* name was in your res directory, without the type extension.
* The easiest way to construct this form is
* <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre>
* </li>
* </ul>
*
* <p>Note that if this function is called for read-only input (mode is "r")
* on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor}
* for you with a MIME type of "*/*". This allows such callers to benefit
* from any built-in data conversion that a provider implements.
*
* @param uri The desired URI to open.
* @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
* ContentProvider.openAssetFile}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if
* none. If the operation is canceled, then
* {@link OperationCanceledException} will be thrown.
* @return Returns a new ParcelFileDescriptor pointing to the file. You
* own this descriptor and are responsible for closing it when done.
* @throws FileNotFoundException Throws FileNotFoundException of no
* file exists under the URI or the mode is invalid.
*/
@Nullable
public final AssetFileDescriptor openAssetFileDescriptor(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal cancellationSignal) throws FileNotFoundException {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(mode, "mode");
String scheme = uri.getScheme();
if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
if (!"r".equals(mode)) {
throw new FileNotFoundException("Can't write resources: " + uri);
}
OpenResourceIdResult r = getResourceId(uri);
try {
return r.r.openRawResourceFd(r.id);
} catch (Resources.NotFoundException ex) {
throw new FileNotFoundException("Resource does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode));
return new AssetFileDescriptor(pfd, 0, -1);
} else {
if ("r".equals(mode)) {
return openTypedAssetFileDescriptor(uri, "*/*", null, cancellationSignal);
} else {
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
IContentProvider stableProvider = null;
AssetFileDescriptor fd = null;
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = unstableProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
fd = unstableProvider.openAssetFile(mPackageName, uri, mode, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
} catch (DeadObjectException e) {
// The remote process has died... but we only hold an unstable
// reference though, so we might recover!!! Let's try!!!!
// This is exciting!!1!!1!!!!1
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
fd = stableProvider.openAssetFile(mPackageName, uri, mode, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
}
if (stableProvider == null) {
stableProvider = acquireProvider(uri);
}
releaseUnstableProvider(unstableProvider);
unstableProvider = null;
ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(fd.getParcelFileDescriptor(), stableProvider);
// Success! Don't release the provider when exiting, let
// ParcelFileDescriptorInner do that when it is closed.
stableProvider = null;
return new AssetFileDescriptor(pfd, fd.getStartOffset(), fd.getDeclaredLength());
} catch (RemoteException e) {
// Whatever, whatever, we'll go away.
throw new FileNotFoundException("Failed opening content provider: " + uri);
} catch (FileNotFoundException e) {
throw e;
} finally {
if (cancellationSignal != null) {
cancellationSignal.setRemote(null);
}
if (stableProvider != null) {
releaseProvider(stableProvider);
}
if (unstableProvider != null) {
releaseUnstableProvider(unstableProvider);
}
}
}
}
}
use of android.os.ICancellationSignal in project platform_frameworks_base by android.
the class ContentResolver method openTypedAssetFileDescriptor.
/**
* Open a raw file descriptor to access (potentially type transformed)
* data from a "content:" URI. This interacts with the underlying
* {@link ContentProvider#openTypedAssetFile} method of the provider
* associated with the given URI, to retrieve retrieve any appropriate
* data stream for the data stored there.
*
* <p>Unlike {@link #openAssetFileDescriptor}, this function only works
* with "content:" URIs, because content providers are the only facility
* with an associated MIME type to ensure that the returned data stream
* is of the desired type.
*
* <p>All text/* streams are encoded in UTF-8.
*
* @param uri The desired URI to open.
* @param mimeType The desired MIME type of the returned data. This can
* be a pattern such as */*, which will allow the content provider to
* select a type, though there is no way for you to determine what type
* it is returning.
* @param opts Additional provider-dependent options.
* @param cancellationSignal A signal to cancel the operation in progress,
* or null if none. If the operation is canceled, then
* {@link OperationCanceledException} will be thrown.
* @return Returns a new ParcelFileDescriptor from which you can read the
* data stream from the provider. Note that this may be a pipe, meaning
* you can't seek in it. The only seek you should do is if the
* AssetFileDescriptor contains an offset, to move to that offset before
* reading. You own this descriptor and are responsible for closing it when done.
* @throws FileNotFoundException Throws FileNotFoundException of no
* data of the desired type exists under the URI.
*/
@Nullable
public final AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri, @NonNull String mimeType, @Nullable Bundle opts, @Nullable CancellationSignal cancellationSignal) throws FileNotFoundException {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(mimeType, "mimeType");
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
IContentProvider stableProvider = null;
AssetFileDescriptor fd = null;
try {
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
remoteCancellationSignal = unstableProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
fd = unstableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
} catch (DeadObjectException e) {
// The remote process has died... but we only hold an unstable
// reference though, so we might recover!!! Let's try!!!!
// This is exciting!!1!!1!!!!1
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
fd = stableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts, remoteCancellationSignal);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
}
if (stableProvider == null) {
stableProvider = acquireProvider(uri);
}
releaseUnstableProvider(unstableProvider);
unstableProvider = null;
ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(fd.getParcelFileDescriptor(), stableProvider);
// Success! Don't release the provider when exiting, let
// ParcelFileDescriptorInner do that when it is closed.
stableProvider = null;
return new AssetFileDescriptor(pfd, fd.getStartOffset(), fd.getDeclaredLength());
} catch (RemoteException e) {
// Whatever, whatever, we'll go away.
throw new FileNotFoundException("Failed opening content provider: " + uri);
} catch (FileNotFoundException e) {
throw e;
} finally {
if (cancellationSignal != null) {
cancellationSignal.setRemote(null);
}
if (stableProvider != null) {
releaseProvider(stableProvider);
}
if (unstableProvider != null) {
releaseUnstableProvider(unstableProvider);
}
}
}
use of android.os.ICancellationSignal in project platform_frameworks_base by android.
the class ContentProviderClient method openTypedAssetFileDescriptor.
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
@Nullable
public final AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri, @NonNull String mimeType, @Nullable Bundle opts, @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
Preconditions.checkNotNull(uri, "uri");
Preconditions.checkNotNull(mimeType, "mimeType");
beforeRemote();
try {
ICancellationSignal remoteSignal = null;
if (signal != null) {
signal.throwIfCanceled();
remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal);
}
return mContentProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts, remoteSignal);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
use of android.os.ICancellationSignal in project platform_frameworks_base by android.
the class ContentProviderClient method query.
/** See {@link ContentProvider#query ContentProvider.query} */
@Nullable
public Cursor query(@NonNull Uri url, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder, @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);
}
final Cursor cursor = mContentProvider.query(mPackageName, url, projection, selection, selectionArgs, sortOrder, remoteCancellationSignal);
if (cursor == null) {
return null;
}
if ("com.google.android.gms".equals(mPackageName)) {
// They're casting to a concrete subclass, sigh
return cursor;
} else {
return new CursorWrapperInner(cursor);
}
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
}
throw e;
} finally {
afterRemote();
}
}
Aggregations