Initialize UidStates in system ready
This is in preparation of moving the persistence of the persisted appops states. Bug: 266163878 Test: AppOps tests and inspect heapdump Change-Id: I4f6b5b435fa9abfdab1da486b9c3f7cd337e4ed6
This commit is contained in:
@@ -105,6 +105,21 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SparseIntArray getNonDefaultPackageModes(String packageName, int userId) {
|
||||
synchronized (mLock) {
|
||||
ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId);
|
||||
if (packageModes == null) {
|
||||
return new SparseIntArray();
|
||||
}
|
||||
SparseIntArray opModes = packageModes.get(packageName);
|
||||
if (opModes == null) {
|
||||
return new SparseIntArray();
|
||||
}
|
||||
return opModes.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUidMode(int uid, int op) {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -38,6 +38,15 @@ public interface AppOpsCheckingServiceInterface {
|
||||
*/
|
||||
SparseIntArray getNonDefaultUidModes(int uid);
|
||||
|
||||
/**
|
||||
* Returns a copy of non-default app-ops with op as keys and their modes as values for a package
|
||||
* and user.
|
||||
* Returns an empty SparseIntArray if nothing is set.
|
||||
* @param packageName for which we need the app-ops and their modes.
|
||||
* @param userId for which the package is installed in.
|
||||
*/
|
||||
SparseIntArray getNonDefaultPackageModes(String packageName, int userId);
|
||||
|
||||
/**
|
||||
* Returns the app-op mode for a particular app-op of a uid.
|
||||
* Returns default op mode if the op mode for particular uid and op is not set.
|
||||
|
||||
@@ -45,6 +45,13 @@ public class AppOpsCheckingServiceLoggingDecorator implements AppOpsCheckingServ
|
||||
return mService.getNonDefaultUidModes(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SparseIntArray getNonDefaultPackageModes(String packageName, int userId) {
|
||||
Log.i(LOG_TAG, "getNonDefaultPackageModes("
|
||||
+ "packageName = " + packageName + ", userId = " + userId + ") ");
|
||||
return mService.getNonDefaultPackageModes(packageName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUidMode(int uid, int op) {
|
||||
Log.i(LOG_TAG, "getUidMode(uid = " + uid + ", op = " + op + ")");
|
||||
|
||||
@@ -98,6 +98,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION;
|
||||
import android.net.Uri;
|
||||
@@ -162,6 +163,7 @@ import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
import com.android.server.pm.pkg.AndroidPackage;
|
||||
import com.android.server.pm.pkg.PackageState;
|
||||
import com.android.server.pm.pkg.PackageStateInternal;
|
||||
import com.android.server.pm.pkg.component.ParsedAttribution;
|
||||
import com.android.server.policy.AppOpsPolicy;
|
||||
|
||||
@@ -383,6 +385,9 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
/** Package Manager internal. Access via {@link #getPackageManagerInternal()} */
|
||||
private @Nullable PackageManagerInternal mPackageManagerInternal;
|
||||
|
||||
/** User Manager internal. Access via {@link #getUserManagerInternal()} */
|
||||
private @Nullable UserManagerInternal mUserManagerInternal;
|
||||
|
||||
/** Interface for app-op modes.*/
|
||||
@VisibleForTesting
|
||||
AppOpsCheckingServiceInterface mAppOpsCheckingService;
|
||||
@@ -525,22 +530,6 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
pkgOps = null;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
boolean areAllPackageModesDefault = true;
|
||||
if (pkgOps != null) {
|
||||
for (String packageName : pkgOps.keySet()) {
|
||||
if (!mAppOpsCheckingService.arePackageModesDefault(packageName,
|
||||
UserHandle.getUserId(uid))) {
|
||||
areAllPackageModesDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (pkgOps == null || pkgOps.isEmpty())
|
||||
&& mAppOpsCheckingService.areUidModesDefault(uid)
|
||||
&& areAllPackageModesDefault;
|
||||
}
|
||||
|
||||
// Functions for uid mode access and manipulation.
|
||||
public SparseIntArray getNonDefaultUidModes() {
|
||||
return mAppOpsCheckingService.getNonDefaultUidModes(uid);
|
||||
@@ -1076,6 +1065,17 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
synchronized (this) {
|
||||
upgradeLocked(mVersionAtBoot);
|
||||
}
|
||||
initializeUidStates();
|
||||
|
||||
getUserManagerInternal().addUserLifecycleListener(
|
||||
new UserManagerInternal.UserLifecycleListener() {
|
||||
@Override
|
||||
public void onUserCreated(UserInfo user, Object token) {
|
||||
initializeUserUidStates(user.id);
|
||||
}
|
||||
|
||||
// onUserRemoved handled by #removeUser
|
||||
});
|
||||
|
||||
mConstants.startMonitoring(mContext.getContentResolver());
|
||||
mHistoricalRegistry.systemReady(mContext.getContentResolver());
|
||||
@@ -1202,6 +1202,49 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize uid state objects for state contained in the checking service.
|
||||
*/
|
||||
private void initializeUidStates() {
|
||||
UserManagerInternal umi = getUserManagerInternal();
|
||||
int[] userIds = umi.getUserIds();
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < userIds.length; i++) {
|
||||
int userId = userIds[i];
|
||||
initializeUserUidStatesLocked(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeUserUidStates(int userId) {
|
||||
synchronized (this) {
|
||||
initializeUserUidStatesLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeUserUidStatesLocked(int userId) {
|
||||
ArrayMap<String, ? extends PackageStateInternal> packageStates =
|
||||
getPackageManagerInternal().getPackageStates();
|
||||
for (int j = 0; j < packageStates.size(); j++) {
|
||||
PackageStateInternal packageState = packageStates.valueAt(j);
|
||||
int uid = UserHandle.getUid(userId, packageState.getAppId());
|
||||
UidState uidState = getUidStateLocked(uid, true);
|
||||
if (uidState.pkgOps == null) {
|
||||
uidState.pkgOps = new ArrayMap<>();
|
||||
}
|
||||
String packageName = packageStates.keyAt(j);
|
||||
Ops ops = new Ops(packageName, uidState);
|
||||
uidState.pkgOps.put(packageName, ops);
|
||||
|
||||
SparseIntArray packageModes =
|
||||
mAppOpsCheckingService.getNonDefaultPackageModes(packageName, userId);
|
||||
for (int k = 0; k < packageModes.size(); k++) {
|
||||
int code = packageModes.get(k);
|
||||
ops.put(code, new Op(uidState, packageName, code, uid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a policy for handling app ops.
|
||||
*
|
||||
@@ -1687,13 +1730,6 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
pkgOps.remove(ops.packageName);
|
||||
mAppOpsCheckingService.removePackage(ops.packageName,
|
||||
UserHandle.getUserId(uidState.uid));
|
||||
if (pkgOps.isEmpty()) {
|
||||
uidState.pkgOps = null;
|
||||
}
|
||||
if (uidState.isDefault()) {
|
||||
uidState.clear();
|
||||
mUidStates.remove(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2147,10 +2183,6 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
UserHandle.getUserId(uidState.uid));
|
||||
}
|
||||
}
|
||||
if (uidState.isDefault()) {
|
||||
uidState.clear();
|
||||
mUidStates.remove(uidState.uid);
|
||||
}
|
||||
if (uidChanged) {
|
||||
uidState.evalForegroundOps();
|
||||
}
|
||||
@@ -3587,6 +3619,20 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
|
||||
return mPackageManagerInternal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link UserManagerInternal}
|
||||
*/
|
||||
private @NonNull UserManagerInternal getUserManagerInternal() {
|
||||
if (mUserManagerInternal == null) {
|
||||
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
|
||||
}
|
||||
if (mUserManagerInternal == null) {
|
||||
throw new IllegalStateException("UserManagerInternal not loaded");
|
||||
}
|
||||
|
||||
return mUserManagerInternal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a restriction description matching the properties of the package.
|
||||
*
|
||||
|
||||
@@ -71,6 +71,10 @@ class AppOpService(
|
||||
return opNameMapToOpIntMap(getUidModes(uid))
|
||||
}
|
||||
|
||||
override fun getNonDefaultPackageModes(packageName: String, userId: Int): SparseIntArray {
|
||||
return opNameMapToOpIntMap(getPackageModes(packageName, userId))
|
||||
}
|
||||
|
||||
override fun getUidMode(uid: Int, op: Int): Int {
|
||||
val appId = UserHandle.getAppId(uid)
|
||||
val userId = UserHandle.getUserId(uid)
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.content.pm.PackageManagerInternal;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -51,12 +52,14 @@ import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.modules.utils.TypedXmlPullParser;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemServerInitThreadPool;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
import com.android.server.pm.pkg.PackageStateInternal;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -188,6 +191,11 @@ public class AppOpsUpgradeTest {
|
||||
|
||||
// Stub out package calls to disable AppOpsService#updatePermissionRevokedCompat
|
||||
doReturn(null).when(mPackageManager).getPackagesForUid(anyInt());
|
||||
|
||||
doReturn(new ArrayMap<String, PackageStateInternal>()).when(mPackageManagerInternal)
|
||||
.getPackageStates();
|
||||
|
||||
doReturn(new int[] {0}).when(mUserManagerInternal).getUserIds();
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
Reference in New Issue
Block a user