Merge "Introduce AuthenticationRequiredException, and @hide RecoverableSecurityException."

This commit is contained in:
TreeHugger Robot
2017-03-23 22:12:20 +00:00
committed by Android (Google) Code Review
6 changed files with 177 additions and 102 deletions

View File

@@ -4297,6 +4297,14 @@ package android.app {
field public java.lang.String serviceDetails;
}
public final class AuthenticationRequiredException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public AuthenticationRequiredException(java.lang.Throwable, android.app.PendingIntent);
method public int describeContents();
method public android.app.PendingIntent getUserAction();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.AuthenticationRequiredException> CREATOR;
}
public final class AutomaticZenRule implements android.os.Parcelable {
ctor public AutomaticZenRule(java.lang.String, android.content.ComponentName, android.net.Uri, int, boolean);
ctor public AutomaticZenRule(android.os.Parcel);
@@ -5708,17 +5716,6 @@ package android.app {
field public static final int STYLE_SPINNER = 0; // 0x0
}
public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public RecoverableSecurityException(java.lang.Throwable, java.lang.CharSequence, android.app.RemoteAction);
method public int describeContents();
method public android.app.RemoteAction getUserAction();
method public java.lang.CharSequence getUserMessage();
method public void showAsDialog(android.app.Activity);
method public void showAsNotification(android.content.Context, java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.RecoverableSecurityException> CREATOR;
}
public final class RemoteAction implements android.os.Parcelable {
ctor public RemoteAction(android.graphics.drawable.Icon, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public android.app.RemoteAction clone();

View File

@@ -4441,6 +4441,14 @@ package android.app {
field public java.lang.String serviceDetails;
}
public final class AuthenticationRequiredException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public AuthenticationRequiredException(java.lang.Throwable, android.app.PendingIntent);
method public int describeContents();
method public android.app.PendingIntent getUserAction();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.AuthenticationRequiredException> CREATOR;
}
public final class AutomaticZenRule implements android.os.Parcelable {
ctor public AutomaticZenRule(java.lang.String, android.content.ComponentName, android.net.Uri, int, boolean);
ctor public AutomaticZenRule(android.os.Parcel);
@@ -5900,17 +5908,6 @@ package android.app {
field public static final int STYLE_SPINNER = 0; // 0x0
}
public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public RecoverableSecurityException(java.lang.Throwable, java.lang.CharSequence, android.app.RemoteAction);
method public int describeContents();
method public android.app.RemoteAction getUserAction();
method public java.lang.CharSequence getUserMessage();
method public void showAsDialog(android.app.Activity);
method public void showAsNotification(android.content.Context, java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.RecoverableSecurityException> CREATOR;
}
public final class RemoteAction implements android.os.Parcelable {
ctor public RemoteAction(android.graphics.drawable.Icon, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public android.app.RemoteAction clone();

View File

@@ -4307,6 +4307,14 @@ package android.app {
field public java.lang.String serviceDetails;
}
public final class AuthenticationRequiredException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public AuthenticationRequiredException(java.lang.Throwable, android.app.PendingIntent);
method public int describeContents();
method public android.app.PendingIntent getUserAction();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.AuthenticationRequiredException> CREATOR;
}
public final class AutomaticZenRule implements android.os.Parcelable {
ctor public AutomaticZenRule(java.lang.String, android.content.ComponentName, android.net.Uri, int, boolean);
ctor public AutomaticZenRule(android.os.Parcel);
@@ -5719,17 +5727,6 @@ package android.app {
field public static final int STYLE_SPINNER = 0; // 0x0
}
public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
ctor public RecoverableSecurityException(java.lang.Throwable, java.lang.CharSequence, android.app.RemoteAction);
method public int describeContents();
method public android.app.RemoteAction getUserAction();
method public java.lang.CharSequence getUserMessage();
method public void showAsDialog(android.app.Activity);
method public void showAsNotification(android.content.Context, java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.RecoverableSecurityException> CREATOR;
}
public final class RemoteAction implements android.os.Parcelable {
ctor public RemoteAction(android.graphics.drawable.Icon, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public android.app.RemoteAction clone();

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
/**
* Specialization of {@link SecurityException} that is thrown when authentication is needed from the
* end user before viewing the content.
* <p>
* This exception is only appropriate where there is a concrete action the user can take to
* authorize and make forward progress, such as confirming or entering authentication credentials,
* or granting access via other means.
* <p class="note">
* Note: legacy code that receives this exception may treat it as a general
* {@link SecurityException}, and thus there is no guarantee that the action contained will be
* invoked by the user.
* </p>
*/
public final class AuthenticationRequiredException extends SecurityException implements Parcelable {
private static final String TAG = "AuthenticationRequiredException";
private final PendingIntent mUserAction;
/** {@hide} */
public AuthenticationRequiredException(Parcel in) {
this(new SecurityException(in.readString()), PendingIntent.CREATOR.createFromParcel(in));
}
/**
* Create an instance ready to be thrown.
*
* @param cause original cause with details designed for engineering
* audiences.
* @param userAction primary action that will initiate the recovery. This
* must launch an activity that is expected to set
* {@link Activity#setResult(int)} before finishing to
* communicate the final status of the recovery. For example,
* apps that observe {@link Activity#RESULT_OK} may choose to
* immediately retry their operation. If this exception was
* thrown from a {@link ContentProvider}, you should also send
* any relevant {@link ContentResolver#notifyChange} events to
* trigger reloading of data.
*/
public AuthenticationRequiredException(Throwable cause, PendingIntent userAction) {
super(cause.getMessage());
mUserAction = Preconditions.checkNotNull(userAction);
}
/**
* Return primary action that will initiate the authorization.
*/
public PendingIntent getUserAction() {
return mUserAction;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getMessage());
mUserAction.writeToParcel(dest, flags);
}
public static final Creator<AuthenticationRequiredException> CREATOR =
new Creator<AuthenticationRequiredException>() {
@Override
public AuthenticationRequiredException createFromParcel(Parcel source) {
return new AuthenticationRequiredException(source);
}
@Override
public AuthenticationRequiredException[] newArray(int size) {
return new AuthenticationRequiredException[size];
}
};
}

View File

@@ -45,7 +45,8 @@ import com.android.internal.util.Preconditions;
* Note: legacy code that receives this exception may treat it as a general
* {@link SecurityException}, and thus there is no guarantee that the messages
* contained will be shown to the end user.
* </p>
*
* @hide
*/
public final class RecoverableSecurityException extends SecurityException implements Parcelable {
private static final String TAG = "RecoverableSecurityException";

View File

@@ -38,7 +38,7 @@ import static android.provider.DocumentsContract.isTreeUri;
import android.Manifest;
import android.annotation.CallSuper;
import android.annotation.Nullable;
import android.app.RecoverableSecurityException;
import android.app.AuthenticationRequiredException;
import android.content.ClipDescription;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -235,10 +235,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* {@link Document#COLUMN_DOCUMENT_ID}. You must allocate a new
* {@link Document#COLUMN_DOCUMENT_ID} to represent the document, which must
* not change once returned.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param parentDocumentId the parent directory to create the new document
* under.
@@ -247,6 +243,10 @@ public abstract class DocumentsProvider extends ContentProvider {
* @param displayName the display name of the new document. The provider may
* alter this name to meet any internal constraints, such as
* avoiding conflicting names.
* @throws AuthenticationRequiredException If authentication is required from the user (such as
* login credentials), but it is not guaranteed that the client will handle this
* properly.
*/
@SuppressWarnings("unused")
public String createDocument(String parentDocumentId, String mimeType, String displayName)
@@ -262,15 +262,14 @@ public abstract class DocumentsProvider extends ContentProvider {
* URI permission grants will be updated to point at the new document. If
* the original {@link Document#COLUMN_DOCUMENT_ID} is still valid after the
* rename, return {@code null}.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param documentId the document to rename.
* @param displayName the updated display name of the document. The provider
* may alter this name to meet any internal constraints, such as
* avoiding conflicting names.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
@SuppressWarnings("unused")
public String renameDocument(String documentId, String displayName)
@@ -286,12 +285,11 @@ public abstract class DocumentsProvider extends ContentProvider {
* call (such as documents inside a directory) the implementor is
* responsible for revoking those permissions using
* {@link #revokeDocumentPermission(String)}.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param documentId the document to delete.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
@SuppressWarnings("unused")
public void deleteDocument(String documentId) throws FileNotFoundException {
@@ -305,13 +303,12 @@ public abstract class DocumentsProvider extends ContentProvider {
* the same document provider. Upon completion returns the document id of
* the copied document at the target destination. {@code null} must never
* be returned.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param sourceDocumentId the document to copy.
* @param targetParentDocumentId the target document to be copied into as a child.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
@SuppressWarnings("unused")
public String copyDocument(String sourceDocumentId, String targetParentDocumentId)
@@ -329,15 +326,14 @@ public abstract class DocumentsProvider extends ContentProvider {
*
* <p>It's the responsibility of the provider to revoke grants if the document
* is no longer accessible using <code>sourceDocumentId</code>.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param sourceDocumentId the document to move.
* @param sourceParentDocumentId the parent of the document to move.
* @param targetParentDocumentId the target document to be a new parent of the
* source document.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
@SuppressWarnings("unused")
public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
@@ -355,11 +351,11 @@ public abstract class DocumentsProvider extends ContentProvider {
* <p>It's the responsibility of the provider to revoke grants if the document is
* removed from the last parent, and effectively the document is deleted.
*
* <p>{@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
* @param documentId the document to remove.
* @param parentDocumentId the parent of the document to move.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
@SuppressWarnings("unused")
public void removeDocument(String documentId, String parentDocumentId)
@@ -377,9 +373,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* <p>This API assumes that document ID has enough info to infer the root.
* Different roots should use different document ID to refer to the same
* document.
* <p>{@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.perly.
*
*
* @param parentDocumentId the document from which the path starts if not null,
@@ -388,6 +381,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* @return the path of the requested document. If parentDocumentId is null
* returned root ID must not be null. If parentDocumentId is not null
* returned root ID must be null.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
public Path findDocumentPath(@Nullable String parentDocumentId, String childDocumentId)
throws FileNotFoundException {
@@ -397,7 +393,7 @@ public abstract class DocumentsProvider extends ContentProvider {
/**
* Creates an intent sender for a web link, if the document is web linkable.
* <p>
* {@link RecoverableSecurityException} can be thrown if user does not have
* {@link AuthenticationRequiredException} can be thrown if user does not have
* sufficient permission for the linked document. Before any new permissions
* are granted for the linked document, a visible UI must be shown, so the
* user can explicitly confirm whether the permission grants are expected.
@@ -414,6 +410,9 @@ public abstract class DocumentsProvider extends ContentProvider {
*
* @param documentId the document to create a web link intent for.
* @param options additional information, such as list of recipients. Optional.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*
* @see DocumentsContract.Document#FLAG_WEB_LINKABLE
* @see android.app.PendingIntent#getIntentSender
@@ -436,9 +435,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* android.database.ContentObserver, boolean)} with
* {@link DocumentsContract#buildRootsUri(String)} to notify the system.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
*
* @param projection list of {@link Root} columns to put into the cursor. If
* {@code null} all supported columns should be included.
@@ -452,10 +448,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* sorted by {@link Document#COLUMN_LAST_MODIFIED} in descending order, and
* limited to only return the 64 most recently modified documents.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
* <p>
* Recent documents do not support change notifications.
*
* @param projection list of {@link Document} columns to put into the
@@ -472,16 +464,14 @@ public abstract class DocumentsProvider extends ContentProvider {
/**
* Return metadata for the single requested document. You should avoid
* making network requests to keep this request fast.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
*
*
* @param documentId the document to return.
* @param projection list of {@link Document} columns to put into the
* cursor. If {@code null} all supported columns should be
* included.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
public abstract Cursor queryDocument(String documentId, String[] projection)
throws FileNotFoundException;
@@ -509,11 +499,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* you can call {@link ContentResolver#notifyChange(Uri,
* android.database.ContentObserver, boolean)} with that Uri to send change
* notifications.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
*
*
* @param parentDocumentId the directory to return children for.
* @param projection list of {@link Document} columns to put into the
@@ -525,6 +510,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* may be unordered. This ordering is a hint that can be used to
* prioritize how data is fetched from the network, but UI may
* always enforce a specific ordering.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
* @see DocumentsContract#EXTRA_LOADING
* @see DocumentsContract#EXTRA_INFO
* @see DocumentsContract#EXTRA_ERROR
@@ -552,10 +540,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* you can call {@link ContentResolver#notifyChange(Uri,
* android.database.ContentObserver, boolean)} with that Uri to send change
* notifications.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
*
* @param parentDocumentId the directory to return children for.
* @param projection list of {@link Document} columns to put into the
@@ -567,6 +551,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* will be used, which may be unordered. See
* {@link ContentResolver#QUERY_ARG_SORT_COLUMNS} for
* details.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*
* @see DocumentsContract#EXTRA_LOADING
* @see DocumentsContract#EXTRA_INFO
@@ -609,16 +596,16 @@ public abstract class DocumentsProvider extends ContentProvider {
* String, String)}. Then you can call {@link ContentResolver#notifyChange(Uri,
* android.database.ContentObserver, boolean)} with that Uri to send change
* notifications.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), or returned as part of
* Cursor's bundle. It is not guaranteed that the client will handle this properly.
*
* @param rootId the root to search under.
* @param query string to match documents against.
* @param projection list of {@link Document} columns to put into the
* cursor. If {@code null} all supported columns should be
* included.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*
* @see DocumentsContract#EXTRA_LOADING
* @see DocumentsContract#EXTRA_INFO
* @see DocumentsContract#EXTRA_ERROR
@@ -641,9 +628,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* implementation queries {@link #queryDocument(String, String[])}, so
* providers may choose to override this as an optimization.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
*/
public String getDocumentType(String documentId) throws FileNotFoundException {
final Cursor cursor = queryDocument(documentId, null);
@@ -669,15 +656,14 @@ public abstract class DocumentsProvider extends ContentProvider {
* <p>
* If you block while downloading content, you should periodically check
* {@link CancellationSignal#isCanceled()} to abort abandoned open requests.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param documentId the document to return.
* @param mode the mode to open with, such as 'r', 'w', or 'rw'.
* @param signal used by the caller to signal if the request should be
* cancelled. May be null.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
* @see ParcelFileDescriptor#open(java.io.File, int, android.os.Handler,
* OnCloseListener)
* @see ParcelFileDescriptor#createReliablePipe()
@@ -697,15 +683,14 @@ public abstract class DocumentsProvider extends ContentProvider {
* If you perform expensive operations to download or generate a thumbnail,
* you should periodically check {@link CancellationSignal#isCanceled()} to
* abort abandoned thumbnail requests.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param documentId the document to return.
* @param sizeHint hint of the optimal thumbnail dimensions.
* @param signal used by the caller to signal if the request should be
* cancelled. May be null.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
* @see Document#FLAG_SUPPORTS_THUMBNAIL
*/
@SuppressWarnings("unused")
@@ -723,10 +708,6 @@ public abstract class DocumentsProvider extends ContentProvider {
* matching the specified MIME type filter.
* <p>
* Virtual documents must have at least one streamable format.
* <p>
* {@link RecoverableSecurityException} can be thrown if more input is required
* from the user (such as insufficient permission), but it is not guaranteed that
* the client will handle this properly.
*
* @param documentId the document to return.
* @param mimeTypeFilter the MIME type filter for the requested format. May
@@ -735,6 +716,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* provider.
* @param signal used by the caller to signal if the request should be
* cancelled. May be null.
* @throws AuthenticationRequiredException If authentication is required from
* the user (such as login credentials), but it is not guaranteed
* that the client will handle this properly.
* @see #getDocumentStreamTypes(String, String)
*/
@SuppressWarnings("unused")