summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorEvan Severson <evanseverson@google.com>2019-12-19 22:04:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-12-19 22:04:40 +0000
commit7f1ce8f9035ddb09a820f286b3ca6776587d8db7 (patch)
treefb43feaa634c5de3996e4de26462a3b2d6b229c7 /core/java/android
parent34824d8167c00adfc30d63e7a4a1dcbb5238ace4 (diff)
parentb252d8bdbf378065ff209cb2135b3324136d226f (diff)
Merge "Create system server component for one-time permissions"
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/pm/PackageManager.java16
-rw-r--r--core/java/android/permission/IPermissionController.aidl1
-rw-r--r--core/java/android/permission/IPermissionManager.aidl6
-rw-r--r--core/java/android/permission/PermissionControllerManager.java14
-rw-r--r--core/java/android/permission/PermissionControllerService.java21
-rw-r--r--core/java/android/permission/PermissionManager.java66
6 files changed, 122 insertions, 2 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 21c9739dd1ee..ee27f4f8345f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3243,6 +3243,15 @@ public abstract class PackageManager {
public static final int FLAG_PERMISSION_REVOKED_COMPAT = FLAG_PERMISSION_REVOKE_ON_UPGRADE;
/**
+ * Permission flag: The permission is one-time and should be revoked automatically on app
+ * inactivity
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_ONE_TIME = 1 << 16;
+
+ /**
* Permission flags: Bitwise or of all permission flags allowing an
* exemption for a restricted permission.
* @hide
@@ -3283,7 +3292,8 @@ public abstract class PackageManager {
| FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
| FLAG_PERMISSION_APPLY_RESTRICTION
| FLAG_PERMISSION_GRANTED_BY_ROLE
- | FLAG_PERMISSION_REVOKED_COMPAT;
+ | FLAG_PERMISSION_REVOKED_COMPAT
+ | FLAG_PERMISSION_ONE_TIME;
/**
* Injected activity in app that forwards user to setting activity of that app.
@@ -4063,7 +4073,8 @@ public abstract class PackageManager {
FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT,
FLAG_PERMISSION_APPLY_RESTRICTION,
FLAG_PERMISSION_GRANTED_BY_ROLE,
- FLAG_PERMISSION_REVOKED_COMPAT
+ FLAG_PERMISSION_REVOKED_COMPAT,
+ FLAG_PERMISSION_ONE_TIME
})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionFlags {}
@@ -7164,6 +7175,7 @@ public abstract class PackageManager {
case FLAG_PERMISSION_APPLY_RESTRICTION: return "APPLY_RESTRICTION";
case FLAG_PERMISSION_GRANTED_BY_ROLE: return "GRANTED_BY_ROLE";
case FLAG_PERMISSION_REVOKED_COMPAT: return "REVOKED_COMPAT";
+ case FLAG_PERMISSION_ONE_TIME: return "ONE_TIME";
default: return Integer.toString(flag);
}
}
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index 26c1ec170834..0483514e6297 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -43,4 +43,5 @@ oneway interface IPermissionController {
String permission, int grantState, in AndroidFuture callback);
void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
void updateUserSensitive(in AndroidFuture callback);
+ void notifyOneTimePermissionSessionTimeout(String packageName);
}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 60c88116f804..2615c98a6d5e 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -20,6 +20,7 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.permission.SplitPermissionInfoParcelable;
+import android.os.UserHandle;
import android.permission.IOnPermissionsChangeListener;
/**
@@ -100,4 +101,9 @@ interface IPermissionManager {
boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId);
List<SplitPermissionInfoParcelable> getSplitPermissions();
+
+ void startOneTimePermissionSession(String packageName, int userId, long timeout,
+ int importanceToResetTimer, int importanceToKeepSessionAlive);
+
+ void stopOneTimePermissionSession(String packageName, int userId);
}
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 421e29ed0542..2a1857fd0027 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -636,4 +636,18 @@ public final class PermissionControllerManager {
return future;
});
}
+
+ /**
+ * Called when a package that has permissions registered as "one-time" is considered
+ * inactive.
+ *
+ * @param packageName The package which became inactive
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
+ public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName) {
+ mRemoteService.run(
+ service -> service.notifyOneTimePermissionSessionTimeout(packageName));
+ }
}
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index f9146637c8cb..5d4561c21e55 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -240,6 +240,18 @@ public abstract class PermissionControllerService extends Service {
@NonNull String permission, @PermissionGrantState int grantState,
@NonNull Consumer<Boolean> callback);
+ /**
+ * Called when a package is considered inactive based on the criteria given by
+ * {@link PermissionManager#startOneTimePermissionSession(String, long, int, int)}.
+ * This method is called at the end of a one-time permission session
+ *
+ * @param packageName The package that has been inactive
+ */
+ @BinderThread
+ public void onOneTimePermissionSessionTimeout(@NonNull String packageName) {
+ throw new AbstractMethodError("Must be overridden in implementing class");
+ }
+
@Override
public final @NonNull IBinder onBind(Intent intent) {
return new IPermissionController.Stub() {
@@ -452,6 +464,15 @@ public abstract class PermissionControllerService extends Service {
onUpdateUserSensitivePermissionFlags();
callback.complete(null);
}
+
+ @Override
+ public void notifyOneTimePermissionSessionTimeout(String packageName) {
+ enforceSomePermissionsGrantedToCaller(
+ Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
+ packageName = Preconditions.checkNotNull(packageName,
+ "packageName cannot be null");
+ onOneTimePermissionSessionTimeout(packageName);
+ }
};
}
}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 09286feee6b9..a3215a47fd62 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -25,6 +25,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityManager;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.IPackageManager;
@@ -284,4 +285,69 @@ public final class PermissionManager {
mSplitPermissionInfoParcelable = parcelable;
}
}
+
+ /**
+ * Starts a one-time permission session for a given package. A one-time permission session is
+ * ended if app becomes inactive. Inactivity is defined as the package's uid importance level
+ * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid
+ * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start
+ * until going > importanceToResetTimer.
+ * <p>
+ * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive
+ * then the session is extended until either the importance goes above
+ * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which
+ * will continue the session and reset the timer.
+ * </p>
+ * <p>
+ * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}.
+ * </p>
+ * <p>
+ * Once the session ends
+ * {@link PermissionControllerService#onOneTimePermissionSessionTimeout(String)} is invoked.
+ * </p>
+ * <p>
+ * Note that if there is currently an active session for a package a new one isn't created and
+ * the existing one isn't changed.
+ * </p>
+ * @param packageName The package to start a one-time permission session for
+ * @param timeoutMillis Number of milliseconds for an app to be in an inactive state
+ * @param importanceToResetTimer The least important level to uid must be to reset the timer
+ * @param importanceToKeepSessionAlive The least important level the uid must be to keep the
+ * session alive
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ Manifest.permission.PACKAGE_USAGE_STATS})
+ public void startOneTimePermissionSession(@NonNull String packageName, long timeoutMillis,
+ @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer,
+ @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) {
+ try {
+ mPermissionManager.startOneTimePermissionSession(packageName, mContext.getUserId(),
+ timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Stops the one-time permission session for the package. The callback to the end of session is
+ * not invoked. If there is no one-time session for the package then nothing happens.
+ *
+ * @param packageName Package to stop the one-time permission session for
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ Manifest.permission.PACKAGE_USAGE_STATS})
+ public void stopOneTimePermissionSession(@NonNull String packageName) {
+ try {
+ mPermissionManager.stopOneTimePermissionSession(packageName,
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
}