Merge "Immediately revoke permission on process kill after a self-revocation"

This commit is contained in:
Thomas Vannet
2022-01-21 20:41:48 +00:00
committed by Android (Google) Code Review
5 changed files with 50 additions and 10 deletions

View File

@@ -835,17 +835,17 @@ 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.
* @param callback Callback called when the revocation request has been completed.
*
* @see Context#revokeOwnPermissionsOnKill(Collection)
*
* @hide
*/
public void revokeOwnPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions) {
@NonNull List<String> permissions, AndroidFuture<Void> callback) {
mRemoteService.postAsync(service -> {
AndroidFuture<Void> future = new AndroidFuture<>();
service.revokeOwnPermissionsOnKill(packageName, permissions, future);
return future;
service.revokeOwnPermissionsOnKill(packageName, permissions, callback);
return callback;
}).whenComplete((result, err) -> {
if (err != null) {
Log.e(TAG, "Failed to self revoke " + String.join(",", permissions)

View File

@@ -162,7 +162,10 @@ public class OneTimePermissionUserManager {
* The delay to wait before revoking on the event an app is terminated. Recommended to be long
* enough so that apps don't lose permission on an immediate restart
*/
private static long getKilledDelayMillis() {
private long getKilledDelayMillis(boolean isSelfRevokedPermissionSession) {
if (isSelfRevokedPermissionSession) {
return 0;
}
return DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS,
PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS);
}
@@ -175,6 +178,18 @@ public class OneTimePermissionUserManager {
mContext.registerReceiver(mUninstallListener, new IntentFilter(Intent.ACTION_UID_REMOVED));
}
void setSelfRevokedPermissionSession(int uid) {
synchronized (mLock) {
PackageInactivityListener listener = mListeners.get(uid);
if (listener == null) {
Log.e(LOG_TAG, "Could not set session for uid " + uid
+ " as self-revoke session: session not found");
return;
}
listener.setSelfRevokedPermissionSession();
}
}
/**
* A class which watches a package for inactivity and notifies the permission controller when
* the package becomes inactive
@@ -189,6 +204,7 @@ public class OneTimePermissionUserManager {
private final int mImportanceToResetTimer;
private final int mImportanceToKeepSessionAlive;
private boolean mIsSelfRevokedPermissionSession;
private boolean mIsAlarmSet;
private boolean mIsFinished;
@@ -255,7 +271,7 @@ public class OneTimePermissionUserManager {
}
onImportanceChanged(mUid, imp);
}
}, mToken, getKilledDelayMillis());
}, mToken, getKilledDelayMillis(mIsSelfRevokedPermissionSession));
return;
}
if (importance > mImportanceToResetTimer) {
@@ -290,6 +306,14 @@ public class OneTimePermissionUserManager {
}
}
/**
* Marks the session as a self-revoke session, which does not delay the revocation when
* the app is restarting.
*/
public void setSelfRevokedPermissionSession() {
mIsSelfRevokedPermissionSession = true;
}
/**
* Set the alarm which will callback when the package is inactive
*/

View File

@@ -66,6 +66,7 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.TriFunction;
import com.android.server.LocalServices;
@@ -560,7 +561,16 @@ public class PermissionManagerService extends IPermissionManager.Stub {
@Override
public void revokeOwnPermissionsOnKill(@NonNull String packageName,
@NonNull List<String> permissions) {
mPermissionManagerServiceImpl.revokeOwnPermissionsOnKill(packageName, permissions);
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
AndroidFuture<Void> future = new AndroidFuture<>();
future.whenComplete((result, err) -> {
if (err == null) {
getOneTimePermissionUserManager(callingUserId)
.setSelfRevokedPermissionSession(callingUid);
}
});
mPermissionManagerServiceImpl.revokeOwnPermissionsOnKill(packageName, permissions, future);
}
@Override

View File

@@ -113,6 +113,7 @@ import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.RoSystemProperties;
@@ -1592,7 +1593,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
}
@Override
public void revokeOwnPermissionsOnKill(String packageName, List<String> permissions) {
public void revokeOwnPermissionsOnKill(String packageName, List<String> permissions,
AndroidFuture<Void> callback) {
final int callingUid = Binder.getCallingUid();
int callingUserId = UserHandle.getUserId(callingUid);
int targetPackageUid = mPackageManagerInt.getPackageUid(packageName, 0, callingUserId);
@@ -1607,7 +1609,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
+ permName + " because it does not hold that permission");
}
}
mPermissionControllerManager.revokeOwnPermissionsOnKill(packageName, permissions);
mPermissionControllerManager.revokeOwnPermissionsOnKill(packageName, permissions,
callback);
}
private boolean mayManageRolePermission(int uid) {

View File

@@ -27,6 +27,7 @@ import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.permission.IOnPermissionsChangeListener;
import android.permission.PermissionManagerInternal;
import com.android.internal.infra.AndroidFuture;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.FileDescriptor;
@@ -343,8 +344,10 @@ public interface PermissionManagerServiceInterface extends PermissionManagerInte
*
* @param packageName The name of the package for which the permissions will be revoked.
* @param permissions List of permissions to be revoked.
* @param callback Callback called when the revocation request has been completed.
*/
void revokeOwnPermissionsOnKill(String packageName, List<String> permissions);
void revokeOwnPermissionsOnKill(String packageName, List<String> permissions,
AndroidFuture<Void> callback);
/**
* Get whether you should show UI with rationale for requesting a permission. You should do this