Merge changes from topics "cherrypick-selfrevokemultiuser-emqfc1tlui", "cherrypick-selfrevokerenameself-lcm1yyzp8i", "presubmit-am-8a6e07e400554464bf71e06db20e4f32", "presubmit-am-d66e407983c84f0f90928a76de0d3ef2" into tm-dev

* changes:
  Rename revokeOwnPermissionsOnKill to revokeSelfPermissionsOnKill
  Self-revocation: Call PermissionControllerManager directly from Context
  Synchronously revoke permissions on OTP session end when kill delay is 0
  Do not leak whether package exists in revokeOwnPermissionsOnKill
This commit is contained in:
Thomas Vannet
2022-03-17 14:47:04 +00:00
committed by Android (Google) Code Review
14 changed files with 41 additions and 90 deletions

View File

@@ -9736,8 +9736,8 @@ package android.content {
method @Nullable public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, @Nullable String, @Nullable android.os.Handler, int);
method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void removeStickyBroadcast(@RequiresPermission android.content.Intent);
method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void removeStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
method public void revokeOwnPermissionOnKill(@NonNull String);
method public void revokeOwnPermissionsOnKill(@NonNull java.util.Collection<java.lang.String>);
method public void revokeSelfPermissionOnKill(@NonNull String);
method public void revokeSelfPermissionsOnKill(@NonNull java.util.Collection<java.lang.String>);
method public abstract void revokeUriPermission(android.net.Uri, int);
method public abstract void revokeUriPermission(String, android.net.Uri, int);
method public abstract void sendBroadcast(@RequiresPermission android.content.Intent);

View File

@@ -10049,9 +10049,9 @@ package android.permission {
method @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String);
method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
method @BinderThread public void onRevokeOwnPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable);
method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable);
method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>);
method @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable);
method @Deprecated @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @BinderThread public void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull android.permission.AdminPermissionControlParams, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);

View File

@@ -77,6 +77,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.system.ErrnoException;
import android.system.Os;
@@ -2180,8 +2181,9 @@ class ContextImpl extends Context {
}
@Override
public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
getSystemService(PermissionManager.class).revokeOwnPermissionsOnKill(permissions);
public void revokeSelfPermissionsOnKill(@NonNull Collection<String> permissions) {
getSystemService(PermissionControllerManager.class).revokeSelfPermissionsOnKill(
getPackageName(), new ArrayList<String>(permissions));
}
@Override

View File

@@ -6508,22 +6508,22 @@ public abstract class Context {
/**
* Triggers the asynchronous revocation of a permission.
* Triggers the asynchronous revocation of a runtime permission. If the permission is not
* currently granted, nothing happens (even if later granted by the user).
*
* @param permName The name of the permission to be revoked.
* @see #revokeOwnPermissionsOnKill(Collection)
* @see #revokeSelfPermissionsOnKill(Collection)
* @throws IllegalArgumentException if the permission is not a runtime permission
*/
public void revokeOwnPermissionOnKill(@NonNull String permName) {
revokeOwnPermissionsOnKill(Collections.singletonList(permName));
public void revokeSelfPermissionOnKill(@NonNull String permName) {
revokeSelfPermissionsOnKill(Collections.singletonList(permName));
}
/**
* Triggers the revocation of one or more permissions for the calling package. A package is only
* able to revoke a permission under the following conditions:
* <ul>
* <li>Each permission in {@code permissions} must be granted to the calling package.
* <li>Each permission in {@code permissions} must be a runtime permission.
* </ul>
* able to revoke runtime permissions. If a permission is not currently granted, it is ignored
* and will not get revoked (even if later granted by the user). Ultimately, you should never
* make assumptions about a permission status as users may grant or revoke them at any time.
* <p>
* Background permissions which have no corresponding foreground permission still granted once
* the revocation is effective will also be revoked.
@@ -6549,8 +6549,9 @@ public abstract class Context {
* @param permissions Collection of permissions to be revoked.
* @see PackageManager#getGroupOfPlatformPermission(String, Executor, Consumer)
* @see PackageManager#getPlatformPermissionsForGroup(String, Executor, Consumer)
* @throws IllegalArgumentException if any of the permissions is not a runtime permission
*/
public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
public void revokeSelfPermissionsOnKill(@NonNull Collection<String> permissions) {
throw new AbstractMethodError("Must be overridden in implementing class");
}

View File

@@ -1036,8 +1036,8 @@ public class ContextWrapper extends Context {
}
@Override
public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
mBase.revokeOwnPermissionsOnKill(permissions);
public void revokeSelfPermissionsOnKill(@NonNull Collection<String> permissions) {
mBase.revokeSelfPermissionsOnKill(permissions);
}
@Override

View File

@@ -59,6 +59,6 @@ oneway interface IPermissionController {
void getHibernationEligibility(
in String packageName,
in AndroidFuture callback);
void revokeOwnPermissionsOnKill(in String packageName, in List<String> permissions,
void revokeSelfPermissionsOnKill(in String packageName, in List<String> permissions,
in AndroidFuture callback);
}

View File

@@ -76,8 +76,6 @@ interface IPermissionManager {
List<SplitPermissionInfoParcelable> getSplitPermissions();
void revokeOwnPermissionsOnKill(String packageName, in List<String> permissions);
void startOneTimePermissionSession(String packageName, int userId, long timeout,
long revokeAfterKilledDelay, int importanceToResetTimer,
int importanceToKeepSessionAlive);

View File

@@ -916,15 +916,15 @@ public final class PermissionControllerManager {
* @param packageName The name of the package for which the permissions will be revoked.
* @param permissions List of permissions to be revoked.
*
* @see Context#revokeOwnPermissionsOnKill(java.util.Collection)
* @see Context#revokeSelfPermissionsOnKill(java.util.Collection)
*
* @hide
*/
public void revokeOwnPermissionsOnKill(@NonNull String packageName,
public void revokeSelfPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions) {
mRemoteService.postAsync(service -> {
AndroidFuture<Void> callback = new AndroidFuture<>();
service.revokeOwnPermissionsOnKill(packageName, permissions, callback);
service.revokeSelfPermissionsOnKill(packageName, permissions, callback);
return callback;
}).whenComplete((result, err) -> {
if (err != null) {

View File

@@ -40,6 +40,7 @@ import android.compat.annotation.Disabled;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -339,10 +340,10 @@ public abstract class PermissionControllerService extends Service {
* @param permissions List of permissions to be revoked.
* @param callback Callback waiting for operation to be complete.
*
* @see PermissionManager#revokeOwnPermissionsOnKill(java.util.Collection)
* @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection)
*/
@BinderThread
public void onRevokeOwnPermissionsOnKill(@NonNull String packageName,
public void onRevokeSelfPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions, @NonNull Runnable callback) {
throw new AbstractMethodError("Must be overridden in implementing class");
}
@@ -703,13 +704,19 @@ public abstract class PermissionControllerService extends Service {
}
@Override
public void revokeOwnPermissionsOnKill(@NonNull String packageName,
public void revokeSelfPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions, @NonNull AndroidFuture callback) {
try {
enforceSomePermissionsGrantedToCaller(
Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
Objects.requireNonNull(callback);
onRevokeOwnPermissionsOnKill(packageName, permissions,
final int callingUid = Binder.getCallingUid();
int targetPackageUid = getPackageManager().getPackageUid(packageName,
PackageManager.PackageInfoFlags.of(0));
if (targetPackageUid != callingUid) {
enforceSomePermissionsGrantedToCaller(
Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
}
onRevokeSelfPermissionsOnKill(packageName, permissions,
() -> callback.complete(null));
} catch (Throwable t) {
callback.completeExceptionally(t);

View File

@@ -76,7 +76,6 @@ import com.android.internal.annotations.Immutable;
import com.android.internal.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -625,19 +624,6 @@ public final class PermissionManager {
}
}
/**
* @see Context#revokeOwnPermissionsOnKill(Collection)
* @hide
*/
public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
try {
mPermissionManager.revokeOwnPermissionsOnKill(mContext.getPackageName(),
new ArrayList<String>(permissions));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Gets the state flags associated with a permission.
*

View File

@@ -272,6 +272,10 @@ public class OneTimePermissionUserManager {
mHandler.removeCallbacksAndMessages(mToken);
if (importance > IMPORTANCE_CACHED) {
if (mRevokeAfterKilledDelay == 0) {
onPackageInactiveLocked();
return;
}
// Delay revocation in case app is restarting
mHandler.postDelayed(() -> {
int imp = mActivityManager.getUidImportance(mUid);

View File

@@ -561,12 +561,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
packageName, userId);
}
@Override
public void revokeOwnPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions) {
mPermissionManagerServiceImpl.revokeOwnPermissionsOnKill(packageName, permissions);
}
@Override
public boolean shouldShowRequestPermissionRationale(String packageName, String permissionName,
int userId) {

View File

@@ -1597,25 +1597,6 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
}
@Override
public void revokeOwnPermissionsOnKill(String packageName, List<String> permissions) {
final int callingUid = Binder.getCallingUid();
int callingUserId = UserHandle.getUserId(callingUid);
int targetPackageUid = mPackageManagerInt.getPackageUid(packageName, 0, callingUserId);
if (targetPackageUid != callingUid) {
throw new SecurityException("uid " + callingUid
+ " cannot revoke permissions for package " + packageName + " with uid "
+ targetPackageUid);
}
for (String permName : permissions) {
if (!checkCallingOrSelfPermission(permName)) {
throw new SecurityException("uid " + callingUid + " cannot revoke permission "
+ permName + " because it does not hold that permission");
}
}
mPermissionControllerManager.revokeOwnPermissionsOnKill(packageName, permissions);
}
private boolean mayManageRolePermission(int uid) {
final PackageManager packageManager = mContext.getPackageManager();
final String[] packageNames = packageManager.getPackagesForUid(uid);

View File

@@ -326,28 +326,6 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
*/
void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId);
/**
* Triggers the revocation of one or more permissions for a package, under the following
* conditions:
* <ul>
* <li>The package {@code packageName} must be under the same UID as the calling process
* (typically, the target package is the calling package).
* <li>Each permission in {@code permissions} must be granted to the package
* {@code packageName}.
* <li>Each permission in {@code permissions} must be a runtime permission.
* </ul>
* <p>
* Background permissions which have no corresponding foreground permission still granted once
* the revocation is effective will also be revoked.
* <p>
* This revocation happens asynchronously and kills all processes running in the same UID as
* {@code packageName}. It will be triggered once it is safe to do so.
*
* @param packageName The name of the package for which the permissions will be revoked.
* @param permissions List of permissions to be revoked.
*/
void revokeOwnPermissionsOnKill(String packageName, List<String> permissions);
/**
* Get 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