diff options
| author | 2017-03-20 22:37:20 +0000 | |
|---|---|---|
| committer | 2017-03-20 22:37:25 +0000 | |
| commit | a0c5f7d869028f25d038c2e9fbbf29b4260a8f63 (patch) | |
| tree | efb99c52958043e765d4171e9992661bee155f13 | |
| parent | 7bd4ea53e943b09cb9be2fc4b45f4f7ed24173d6 (diff) | |
| parent | 780861f2452b519c128289dac836e5a756100e1d (diff) | |
Merge "More RecoverableSecurityException docs."
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | api/removed.txt | 4 | ||||
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | api/system-removed.txt | 4 | ||||
| -rw-r--r-- | api/test-current.txt | 2 | ||||
| -rw-r--r-- | api/test-removed.txt | 4 | ||||
| -rw-r--r-- | core/java/android/app/RecoverableSecurityException.java | 57 |
7 files changed, 58 insertions, 17 deletions
diff --git a/api/current.txt b/api/current.txt index 4e8adf9c6844..7dd31ccdbb49 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5705,7 +5705,7 @@ package android.app { 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); + 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; } diff --git a/api/removed.txt b/api/removed.txt index 148f3f1e3281..04c9c35428b3 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -4,6 +4,10 @@ package android.app { method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); } + public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable { + method public deprecated void showAsNotification(android.content.Context); + } + } package android.app.admin { diff --git a/api/system-current.txt b/api/system-current.txt index 1b0264bb8525..99fb44d6a8b6 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5906,7 +5906,7 @@ package android.app { 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); + 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; } diff --git a/api/system-removed.txt b/api/system-removed.txt index bd535d2be513..640dc81877a1 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -4,6 +4,10 @@ package android.app { method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); } + public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable { + method public deprecated void showAsNotification(android.content.Context); + } + } package android.app.admin { diff --git a/api/test-current.txt b/api/test-current.txt index 8b5e86510617..17648d6f0560 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5716,7 +5716,7 @@ package android.app { 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); + 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; } diff --git a/api/test-removed.txt b/api/test-removed.txt index 148f3f1e3281..04c9c35428b3 100644 --- a/api/test-removed.txt +++ b/api/test-removed.txt @@ -4,6 +4,10 @@ package android.app { method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); } + public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable { + method public deprecated void showAsNotification(android.content.Context); + } + } package android.app.admin { diff --git a/core/java/android/app/RecoverableSecurityException.java b/core/java/android/app/RecoverableSecurityException.java index 540d1cda1edd..8612f186ade4 100644 --- a/core/java/android/app/RecoverableSecurityException.java +++ b/core/java/android/app/RecoverableSecurityException.java @@ -16,8 +16,9 @@ package android.app; +import android.content.ContentProvider; +import android.content.ContentResolver; import android.content.Context; -import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcel; @@ -31,7 +32,15 @@ import com.android.internal.util.Preconditions; * <p> * This exception is only appropriate where there is a concrete action the user * can take to recover and make forward progress, such as confirming or entering - * authentication credentials. + * authentication credentials, or granting access. + * <p> + * If the receiving app is actively involved with the user, it should present + * the contained recovery details to help the user make forward progress. The + * {@link #showAsDialog(Activity)} and + * {@link #showAsNotification(Context, String)} methods are provided as a + * convenience, but receiving apps are encouraged to use + * {@link #getUserMessage()} and {@link #getUserAction()} to integrate in a more + * natural way if relevant. * <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 messages @@ -66,7 +75,10 @@ public final class RecoverableSecurityException extends SecurityException implem * {@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. + * 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 RecoverableSecurityException(Throwable cause, CharSequence userMessage, RemoteAction userAction) { @@ -101,6 +113,20 @@ public final class RecoverableSecurityException extends SecurityException implem return mUserAction; } + /** @removed */ + @Deprecated + public void showAsNotification(Context context) { + final NotificationManager nm = context.getSystemService(NotificationManager.class); + + // Create a channel per-sender, since we don't want one poorly behaved + // remote app to cause all of our notifications to be blocked + final String channelId = TAG + "_" + mUserAction.getActionIntent().getCreatorUid(); + nm.createNotificationChannel(new NotificationChannel(channelId, TAG, + NotificationManager.IMPORTANCE_DEFAULT)); + + showAsNotification(context, channelId); + } + /** * Convenience method that will show a very simple notification populated * with the details from this exception. @@ -114,23 +140,20 @@ public final class RecoverableSecurityException extends SecurityException implem * <p> * This method will only display the most recent exception from any single * remote UID; notifications from older exceptions will always be replaced. + * + * @param channelId the {@link NotificationChannel} to use, which must have + * been already created using + * {@link NotificationManager#createNotificationChannel}. */ - public void showAsNotification(Context context) { + public void showAsNotification(Context context, String channelId) { final NotificationManager nm = context.getSystemService(NotificationManager.class); - - // Create a channel per-sender, since we don't want one poorly behaved - // remote app to cause all of our notifications to be blocked - final String tag = TAG + "_" + mUserAction.getActionIntent().getCreatorUid(); - nm.createNotificationChannel(new NotificationChannel(tag, TAG, - NotificationManager.IMPORTANCE_DEFAULT)); - - final Notification.Builder builder = new Notification.Builder(context, tag) + final Notification.Builder builder = new Notification.Builder(context, channelId) .setSmallIcon(com.android.internal.R.drawable.ic_print_error) .setContentTitle(mUserAction.getTitle()) .setContentText(mUserMessage) .setContentIntent(mUserAction.getActionIntent()) .setCategory(Notification.CATEGORY_ERROR); - nm.notify(tag, 0, builder.build()); + nm.notify(TAG, mUserAction.getActionIntent().getCreatorUid(), builder.build()); } /** @@ -164,7 +187,13 @@ public final class RecoverableSecurityException extends SecurityException implem ft.commitAllowingStateLoss(); } - /** {@hide} */ + /** + * Implementation detail for + * {@link RecoverableSecurityException#showAsDialog(Activity)}; needs to + * remain static to be recreated across orientation changes. + * + * @hide + */ public static class LocalDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { |