Merge "Merge "Make sure to always upgrade runtime permissions" into qt-dev am: 3fb12ba490" into qt-r1-dev
am: d80e267260
Change-Id: I6002bcd9521bf32e9b500025379bf641535ed10f
This commit is contained in:
@@ -985,4 +985,13 @@ public abstract class PackageManagerInternal {
|
||||
* @return true if default permissions
|
||||
*/
|
||||
public abstract boolean wereDefaultPermissionsGrantedSinceBoot(int userId);
|
||||
|
||||
/**
|
||||
* Get fingerprint of build that updated the runtime permissions for a user.
|
||||
*
|
||||
* @param userId The user to update
|
||||
* @param fingerPrint The fingerprint to set
|
||||
*/
|
||||
public abstract void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
|
||||
@UserIdInt int userId);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,6 @@ import com.android.server.pm.dex.PackageDexUsage;
|
||||
import com.android.server.pm.dex.ViewCompiler;
|
||||
import com.android.server.pm.permission.BasePermission;
|
||||
import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
|
||||
import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
|
||||
import com.android.server.pm.permission.PermissionManagerService;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
|
||||
@@ -2415,15 +2414,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
LocalServices.getService(PackageManagerInternal.class),
|
||||
mPackages);
|
||||
mPermissionManager = PermissionManagerService.create(context,
|
||||
new DefaultPermissionGrantedCallback() {
|
||||
@Override
|
||||
public void onDefaultRuntimePermissionsGranted(int userId) {
|
||||
synchronized(mPackages) {
|
||||
mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
|
||||
mDefaultPermissionsGrantedUsers.put(userId, userId);
|
||||
}
|
||||
}
|
||||
}, mPackages /*externalLock*/);
|
||||
mPackages /*externalLock*/);
|
||||
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
|
||||
mSettings = new Settings(Environment.getDataDirectory(),
|
||||
mPermissionManager.getPermissionSettings(), mPackages);
|
||||
@@ -24927,6 +24918,14 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return mDefaultPermissionPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
|
||||
@UserIdInt int userId) {
|
||||
synchronized (mPackages) {
|
||||
mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mPackages")
|
||||
|
||||
@@ -1306,9 +1306,8 @@ public final class Settings {
|
||||
.areDefaultRuntimePermissionsGrantedLPr(userId);
|
||||
}
|
||||
|
||||
void onDefaultRuntimePermissionsGrantedLPr(int userId) {
|
||||
mRuntimePermissionsPersistence
|
||||
.onDefaultRuntimePermissionsGrantedLPr(userId);
|
||||
void setRuntimePermissionsFingerPrintLPr(@NonNull String fingerPrint, @UserIdInt int userId) {
|
||||
mRuntimePermissionsPersistence.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
|
||||
}
|
||||
|
||||
int getDefaultRuntimePermissionsVersionLPr(int userId) {
|
||||
@@ -5149,8 +5148,9 @@ public final class Settings {
|
||||
}
|
||||
|
||||
@GuardedBy("Settings.this.mLock")
|
||||
public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
|
||||
mFingerprints.put(userId, Build.FINGERPRINT);
|
||||
public void setRuntimePermissionsFingerPrintLPr(@NonNull String fingerPrint,
|
||||
@UserIdInt int userId) {
|
||||
mFingerprints.put(userId, fingerPrint);
|
||||
writePermissionsForUserAsyncLPr(userId);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,18 +218,11 @@ public final class DefaultPermissionGrantPolicy {
|
||||
private final Object mLock = new Object();
|
||||
private final PackageManagerInternal mServiceInternal;
|
||||
private final PermissionManagerService mPermissionManager;
|
||||
private final DefaultPermissionGrantedCallback mPermissionGrantedCallback;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();
|
||||
|
||||
public interface DefaultPermissionGrantedCallback {
|
||||
/** Callback when permissions have been granted */
|
||||
void onDefaultRuntimePermissionsGranted(int userId);
|
||||
}
|
||||
|
||||
DefaultPermissionGrantPolicy(Context context, Looper looper,
|
||||
@Nullable DefaultPermissionGrantedCallback callback,
|
||||
@NonNull PermissionManagerService permissionManager) {
|
||||
mContext = context;
|
||||
mHandler = new Handler(looper) {
|
||||
@@ -244,7 +237,6 @@ public final class DefaultPermissionGrantPolicy {
|
||||
}
|
||||
}
|
||||
};
|
||||
mPermissionGrantedCallback = callback;
|
||||
mPermissionManager = permissionManager;
|
||||
mServiceInternal = LocalServices.getService(PackageManagerInternal.class);
|
||||
}
|
||||
@@ -756,10 +748,6 @@ public final class DefaultPermissionGrantPolicy {
|
||||
grantPermissionsToSystemPackage(systemCaptionsServicePackageName, userId,
|
||||
MICROPHONE_PERMISSIONS);
|
||||
}
|
||||
|
||||
if (mPermissionGrantedCallback != null) {
|
||||
mPermissionGrantedCallback.onDefaultRuntimePermissionsGranted(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultSystemHandlerActivityPackageForCategory(String category, int userId) {
|
||||
|
||||
@@ -95,7 +95,6 @@ import com.android.server.pm.PackageManagerServiceUtils;
|
||||
import com.android.server.pm.PackageSetting;
|
||||
import com.android.server.pm.SharedUserSetting;
|
||||
import com.android.server.pm.UserManagerService;
|
||||
import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
|
||||
import com.android.server.pm.permission.PermissionsState.PermissionState;
|
||||
|
||||
@@ -220,7 +219,6 @@ public class PermissionManagerService {
|
||||
mRuntimePermissionStateChangedListeners = new ArrayList<>();
|
||||
|
||||
PermissionManagerService(Context context,
|
||||
@Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
|
||||
@NonNull Object externalLock) {
|
||||
mContext = context;
|
||||
mLock = externalLock;
|
||||
@@ -235,7 +233,7 @@ public class PermissionManagerService {
|
||||
Watchdog.getInstance().addThread(mHandler);
|
||||
|
||||
mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
|
||||
context, mHandlerThread.getLooper(), defaultGrantCallback, this);
|
||||
context, mHandlerThread.getLooper(), this);
|
||||
SystemConfig systemConfig = SystemConfig.getInstance();
|
||||
mSystemPermissions = systemConfig.getSystemPermissions();
|
||||
mGlobalGids = systemConfig.getGlobalGids();
|
||||
@@ -273,14 +271,13 @@ public class PermissionManagerService {
|
||||
* lock created by the permission manager itself.
|
||||
*/
|
||||
public static PermissionManagerServiceInternal create(Context context,
|
||||
@Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
|
||||
@NonNull Object externalLock) {
|
||||
final PermissionManagerServiceInternal permMgrInt =
|
||||
LocalServices.getService(PermissionManagerServiceInternal.class);
|
||||
if (permMgrInt != null) {
|
||||
return permMgrInt;
|
||||
}
|
||||
new PermissionManagerService(context, defaultGrantCallback, externalLock);
|
||||
new PermissionManagerService(context, externalLock);
|
||||
return LocalServices.getService(PermissionManagerServiceInternal.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,13 +37,16 @@ import android.content.pm.PermissionInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.permission.PermissionManagerInternal;
|
||||
import android.provider.Telephony;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.FgThread;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
@@ -60,6 +63,13 @@ import java.util.concurrent.CountDownLatch;
|
||||
*/
|
||||
public final class PermissionPolicyService extends SystemService {
|
||||
private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/** Whether the user is started but not yet stopped */
|
||||
@GuardedBy("mLock")
|
||||
private final SparseBooleanArray mIsStarted = new SparseBooleanArray();
|
||||
|
||||
public PermissionPolicyService(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -71,17 +81,22 @@ public final class PermissionPolicyService extends SystemService {
|
||||
public void onStart() {
|
||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
final PermissionManagerInternal permManagerInternal = LocalServices.getService(
|
||||
PermissionManagerInternal.class);
|
||||
|
||||
packageManagerInternal.getPackageList(new PackageListObserver() {
|
||||
@Override
|
||||
public void onPackageAdded(String packageName, int uid) {
|
||||
synchronizePackagePermissionsAndAppOpsForUser(getContext(), packageName,
|
||||
UserHandle.getUserId(uid));
|
||||
onPackageChanged(packageName, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageChanged(String packageName, int uid) {
|
||||
synchronizePackagePermissionsAndAppOpsForUser(getContext(), packageName,
|
||||
UserHandle.getUserId(uid));
|
||||
final int userId = UserHandle.getUserId(uid);
|
||||
|
||||
if (isStarted(userId)) {
|
||||
synchronizePackagePermissionsAndAppOpsForUser(packageName, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,20 +104,75 @@ public final class PermissionPolicyService extends SystemService {
|
||||
/* do nothing */
|
||||
}
|
||||
});
|
||||
|
||||
permManagerInternal.addOnRuntimePermissionStateChangedListener(
|
||||
(packageName, changedUserId) -> {
|
||||
if (isStarted(changedUserId)) {
|
||||
synchronizePackagePermissionsAndAppOpsForUser(packageName, changedUserId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (DEBUG) Slog.i(LOG_TAG, "onBootPhase(" + phase + ")");
|
||||
|
||||
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
|
||||
final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
|
||||
|
||||
// For some users we might not receive a onStartUser, hence force one here
|
||||
for (int userId : um.getUserIds()) {
|
||||
if (um.isUserRunning(userId)) {
|
||||
onStartUser(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the user is started but not yet stopped
|
||||
*/
|
||||
private boolean isStarted(@UserIdInt int userId) {
|
||||
synchronized (mLock) {
|
||||
return mIsStarted.get(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartUser(@UserIdInt int userId) {
|
||||
grantOrUpgradeDefaultRuntimePermissionsInNeeded(getContext(), userId);
|
||||
synchronizePermissionsAndAppOpsForUser(getContext(), userId);
|
||||
startWatchingRuntimePermissionChanges(getContext(), userId);
|
||||
if (DEBUG) Slog.i(LOG_TAG, "onStartUser(" + userId + ")");
|
||||
|
||||
if (isStarted(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
grantOrUpgradeDefaultRuntimePermissionsIfNeeded(userId);
|
||||
|
||||
synchronized (mLock) {
|
||||
mIsStarted.put(userId, true);
|
||||
}
|
||||
|
||||
// Force synchronization as permissions might have changed
|
||||
synchronizePermissionsAndAppOpsForUser(userId);
|
||||
}
|
||||
|
||||
private static void grantOrUpgradeDefaultRuntimePermissionsInNeeded(@NonNull Context context,
|
||||
@UserIdInt int userId) {
|
||||
@Override
|
||||
public void onStopUser(@UserIdInt int userId) {
|
||||
if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + userId + ")");
|
||||
|
||||
synchronized (mLock) {
|
||||
mIsStarted.delete(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int userId) {
|
||||
if (DEBUG) Slog.i(LOG_TAG, "grantOrUpgradeDefaultPermsIfNeeded(" + userId + ")");
|
||||
|
||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
if (packageManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
|
||||
if (DEBUG) Slog.i(LOG_TAG, "defaultPermsWereGrantedSinceBoot(" + userId + ")");
|
||||
|
||||
// Now call into the permission controller to apply policy around permissions
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
@@ -110,7 +180,8 @@ public final class PermissionPolicyService extends SystemService {
|
||||
// there as we are on the main thread and want to block until the work is
|
||||
// completed or we time out.
|
||||
final PermissionControllerManager permissionControllerManager =
|
||||
new PermissionControllerManager(getUserContext(context, UserHandle.of(userId)),
|
||||
new PermissionControllerManager(
|
||||
getUserContext(getContext(), UserHandle.of(userId)),
|
||||
FgThread.getHandler());
|
||||
permissionControllerManager.grantOrUpgradeDefaultRuntimePermissions(
|
||||
FgThread.getExecutor(),
|
||||
@@ -130,19 +201,9 @@ public final class PermissionPolicyService extends SystemService {
|
||||
} catch (InterruptedException e) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void startWatchingRuntimePermissionChanges(@NonNull Context context,
|
||||
int userId) {
|
||||
final PermissionManagerInternal permissionManagerInternal = LocalServices.getService(
|
||||
PermissionManagerInternal.class);
|
||||
permissionManagerInternal.addOnRuntimePermissionStateChangedListener(
|
||||
(packageName, changedUserId) -> {
|
||||
if (userId == changedUserId) {
|
||||
synchronizePackagePermissionsAndAppOpsForUser(context, packageName, userId);
|
||||
}
|
||||
});
|
||||
packageManagerInternal.setRuntimePermissionsFingerPrint(Build.FINGERPRINT, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Context getUserContext(@NonNull Context context,
|
||||
@@ -162,8 +223,14 @@ public final class PermissionPolicyService extends SystemService {
|
||||
/**
|
||||
* Synchronize a single package.
|
||||
*/
|
||||
private static void synchronizePackagePermissionsAndAppOpsForUser(@NonNull Context context,
|
||||
@NonNull String packageName, @UserIdInt int userId) {
|
||||
private void synchronizePackagePermissionsAndAppOpsForUser(@NonNull String packageName,
|
||||
@UserIdInt int userId) {
|
||||
if (DEBUG) {
|
||||
Slog.v(LOG_TAG,
|
||||
"synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", " + userId
|
||||
+ ")");
|
||||
}
|
||||
|
||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0,
|
||||
@@ -172,7 +239,7 @@ public final class PermissionPolicyService extends SystemService {
|
||||
return;
|
||||
}
|
||||
final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
|
||||
getUserContext(context, UserHandle.of(userId)));
|
||||
getUserContext(getContext(), UserHandle.of(userId)));
|
||||
synchroniser.addPackage(pkg.packageName);
|
||||
final String[] sharedPkgNames = packageManagerInternal.getPackagesForSharedUserId(
|
||||
pkg.sharedUserId, userId);
|
||||
@@ -191,12 +258,13 @@ public final class PermissionPolicyService extends SystemService {
|
||||
/**
|
||||
* Synchronize all packages
|
||||
*/
|
||||
private static void synchronizePermissionsAndAppOpsForUser(@NonNull Context context,
|
||||
@UserIdInt int userId) {
|
||||
private void synchronizePermissionsAndAppOpsForUser(@UserIdInt int userId) {
|
||||
if (DEBUG) Slog.i(LOG_TAG, "synchronizePermissionsAndAppOpsForUser(" + userId + ")");
|
||||
|
||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(
|
||||
getUserContext(context, UserHandle.of(userId)));
|
||||
getUserContext(getContext(), UserHandle.of(userId)));
|
||||
packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName));
|
||||
synchronizer.syncPackages();
|
||||
}
|
||||
|
||||
@@ -88,8 +88,7 @@ public class PackageManagerSettingsTests {
|
||||
writeOldFiles();
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
Settings settings =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
||||
@@ -104,8 +103,7 @@ public class PackageManagerSettingsTests {
|
||||
writeOldFiles();
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
Settings settings =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
||||
@@ -122,8 +120,7 @@ public class PackageManagerSettingsTests {
|
||||
writeOldFiles();
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
Settings settings =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
||||
@@ -146,8 +143,7 @@ public class PackageManagerSettingsTests {
|
||||
writeOldFiles();
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
Settings settings =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
||||
@@ -317,8 +313,7 @@ public class PackageManagerSettingsTests {
|
||||
writeOldFiles();
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
Settings settings =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
assertThat(settings.readLPw(createFakeUsers()), is(true));
|
||||
@@ -512,8 +507,7 @@ public class PackageManagerSettingsTests {
|
||||
public void testUpdatePackageSetting03() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
final Settings testSettings01 =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
final SharedUserSetting testUserSetting01 = createSharedUserSetting(
|
||||
@@ -631,8 +625,7 @@ public class PackageManagerSettingsTests {
|
||||
public void testCreateNewSetting03() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final Object lock = new Object();
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, null,
|
||||
lock);
|
||||
PermissionManagerServiceInternal pmInt = PermissionManagerService.create(context, lock);
|
||||
final Settings testSettings01 =
|
||||
new Settings(context.getFilesDir(), pmInt.getPermissionSettings(), lock);
|
||||
final SharedUserSetting testUserSetting01 = createSharedUserSetting(
|
||||
|
||||
Reference in New Issue
Block a user