Add API to hint whether to show on-board UI before a permission request.

bug:21511988

Change-Id: I9d1d7adf34b68074e65510f53b6e642cf784cf6b
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 49f5099..a8eaaae 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3746,6 +3746,7 @@
      *
      * @see #onRequestPermissionsResult(int, String[], int[])
      * @see #checkSelfPermission(String)
+     * @see #canShowRequestPermissionRationale(String)
      */
     public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
         Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
@@ -3770,6 +3771,30 @@
     }
 
     /**
+     * Gets whether you should show UI with rationale for requesting a permission.
+     * You should do this only if you do not have the permission and the context in
+     * which the permission is requested does not clearly communicate to the user
+     * what would be the benefit from granting this permission.
+     * <p>
+     * For example, if you write a camera app, requesting the camera permission
+     * would be expected by the user and no rationale for why it is requested is
+     * needed. If however, the app needs location for tagging photos then a non-tech
+     * savvy user may wonder how location is related to taking photos. In this case
+     * you may choose to show UI with rationale of requesting this permission.
+     * </p>
+     *
+     * @param permission A permission your app wants to request.
+     * @return Whether you can show permission rationale UI.
+     *
+     * @see #checkSelfPermission(String)
+     * @see #requestPermissions(String[], int)
+     * @see #onRequestPermissionsResult(int, String[], int[])
+     */
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        return getPackageManager().shouldShowRequestPermissionRationale(permission);
+    }
+
+    /**
      * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
      * with no options.
      *
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 04f6430..41e3db8 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -486,6 +486,16 @@
     }
 
     @Override
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        try {
+            return mPM.shouldShowRequestPermissionRationale(permission,
+                    mContext.getPackageName(), mContext.getUserId());
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
     public int checkSignatures(String pkg1, String pkg2) {
         try {
             return mPM.checkSignatures(pkg1, pkg2);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index ddff782..00b8c71 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -105,6 +105,9 @@
     void updatePermissionFlags(String permissionName, String packageName, int flagMask,
             int flagValues, int userId);
 
+    boolean shouldShowRequestPermissionRationale(String permissionName,
+            String packageName, int userId);
+
     boolean isProtectedBroadcast(String actionName);
 
     int checkSignatures(String pkg1, String pkg2);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2ca0306..45245e4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2539,6 +2539,19 @@
             @NonNull UserHandle user);
 
     /**
+     * Gets whether you should show UI with rationale for requesting a permission.
+     * You should do this only if you do not have the permission and the context in
+     * which the permission is requested does not clearly communicate to the user
+     * what would be the benefit from grating this permission.
+     *
+     * @param permission A permission your app wants to request.
+     * @return Whether you can show permission rationale UI.
+     *
+     * @hide
+     */
+    public abstract boolean shouldShowRequestPermissionRationale(String permission);
+
+    /**
      * Returns an {@link android.content.Intent} suitable for passing to
      * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
      * which prompts the user to grant permissions to this application.