summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-03-20 22:37:20 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-03-20 22:37:25 +0000
commita0c5f7d869028f25d038c2e9fbbf29b4260a8f63 (patch)
treeefb99c52958043e765d4171e9992661bee155f13
parent7bd4ea53e943b09cb9be2fc4b45f4f7ed24173d6 (diff)
parent780861f2452b519c128289dac836e5a756100e1d (diff)
Merge "More RecoverableSecurityException docs."
-rw-r--r--api/current.txt2
-rw-r--r--api/removed.txt4
-rw-r--r--api/system-current.txt2
-rw-r--r--api/system-removed.txt4
-rw-r--r--api/test-current.txt2
-rw-r--r--api/test-removed.txt4
-rw-r--r--core/java/android/app/RecoverableSecurityException.java57
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) {