diff options
| author | 2019-05-23 23:10:49 +0000 | |
|---|---|---|
| committer | 2019-05-23 23:10:49 +0000 | |
| commit | 3fb12ba4902605668faa22a93f0881ab333ec11d (patch) | |
| tree | 8c9c1b1ccbf1a4443f4e0277fe026fbed9cb77f5 | |
| parent | d6c8e026b94deaf9d7a9d8171fc0e506d55c9168 (diff) | |
| parent | 5f5783e1fd5003f0a6e5abfe20975978382209c3 (diff) | |
Merge "Make sure to always upgrade runtime permissions" into qt-dev
7 files changed, 128 insertions, 74 deletions
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 376a211dbc7d..666508af0207 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -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); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 719e166d5b98..84470f9c2838 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -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") diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a723313dabff..3f00d328090d 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -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); } diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index 9442e5d6914e..22eb9fdaa53c 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -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) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 2a1aee8a441c..267fbf030619 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -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); } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 02911e272692..a799cd92ee83 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -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(); } diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index 50734efacac9..96bb750f0e0e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -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( |