Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7535a18c authored by Evan Severson's avatar Evan Severson
Browse files

Add package to appops state earlier

Use the same entry point that the permission manager service uses when
a package is being installed. This is needed since the package added
broadcast and the non broadcast based PackageMonitor mechanism are both
invoked later than the permission manager service entry point. It had
been observed installed apps were already executing code before the
former two callbacks invoked leading to appop checks from other services
that the app had interacted with or test apps attempting to mutate appop
state.

Test: CtsAppOpsTestCases
Bug: 388994751
Flag: EXEMPT bugfix
Change-Id: I65b9f446c136d37633a8d1540cbced972678e61d
parent 0b924ad1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -233,4 +233,9 @@ public abstract class AppOpsManagerInternal {
     */
    public abstract int getOpRestrictionCount(int code, UserHandle user, String pkg,
            String attributionTag);

    /**
     * Invoke when a package is added.
     */
    public abstract void onPackageAdded(String pkgName, int uid);
}
+56 −36
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ import static android.app.AppOpsManager.opRestrictsRead;
import static android.app.AppOpsManager.opToName;
import static android.app.AppOpsManager.opToPublicName;
import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.EXTRA_REPLACING;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
@@ -363,8 +362,6 @@ public class AppOpsService extends IAppOpsService.Stub {
    @GuardedBy("this")
    @VisibleForTesting
    final SparseArray<UidState> mUidStates = new SparseArray<>();
    @GuardedBy("this")
    private boolean mUidStatesInitialized;

    // A rate limiter to prevent excessive Atom pushing. Used by noteOperation.
    private static final Duration RATE_LIMITER_WINDOW = Duration.ofMillis(10);
@@ -415,6 +412,9 @@ public class AppOpsService extends IAppOpsService.Stub {
    @GuardedBy("this")
    private ArraySet<String> mRarelyUsedPackages = new ArraySet<>();

    @GuardedBy("this")
    private boolean mRarelyUsedPackagesInitialized;

    /** Sampling strategy used for current session */
    @GuardedBy("this")
    @AppOpsManager.SamplingStrategy
@@ -1076,13 +1076,23 @@ public class AppOpsService extends IAppOpsService.Stub {
            String pkgName = intent.getData().getEncodedSchemeSpecificPart().intern();
            int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID);

            if (action.equals(ACTION_PACKAGE_ADDED)
                    && !intent.getBooleanExtra(EXTRA_REPLACING, false)) {
            if (action.equals(ACTION_PACKAGE_REMOVED) && !intent.hasExtra(EXTRA_REPLACING)) {
                onPackageRemoved(pkgName, uid);
            } else if (action.equals(Intent.ACTION_PACKAGE_REPLACED)) {
                onPackageReplaced(pkgName, uid);
            }
        }
    };

    private void onPackageAdded(String pkgName, int uid) {
        PackageInfo pi = getPackageManagerInternal().getPackageInfo(pkgName,
                PackageManager.GET_PERMISSIONS, Process.myUid(),
                UserHandle.getUserId(uid));
                boolean isSamplingTarget = isSamplingTarget(pi);
        synchronized (AppOpsService.this) {
            boolean isSamplingTarget = false;
            if (mRarelyUsedPackagesInitialized) {
                isSamplingTarget = isSamplingTarget(pi);
            }
            if (isSamplingTarget) {
                mRarelyUsedPackages.add(pkgName);
            }
@@ -1094,11 +1104,15 @@ public class AppOpsService extends IAppOpsService.Stub {

            createSandboxUidStateIfNotExistsForAppLocked(uid, null);
        }
            } else if (action.equals(ACTION_PACKAGE_REMOVED) && !intent.hasExtra(EXTRA_REPLACING)) {
    }

    private void onPackageRemoved(String pkgName, int uid) {
        synchronized (AppOpsService.this) {
            packageRemovedLocked(uid, pkgName);
        }
            } else if (action.equals(Intent.ACTION_PACKAGE_REPLACED)) {
    }

    private void onPackageReplaced(String pkgName, int uid) {
        AndroidPackage pkg = getPackageManagerInternal().getPackage(pkgName);
        if (pkg == null) {
            return;
@@ -1108,8 +1122,6 @@ public class AppOpsService extends IAppOpsService.Stub {
            refreshAttributionsLocked(pkg, uid);
        }
    }
        }
    };

    public void systemReady() {
        mVirtualDeviceManagerInternal = LocalServices.getService(
@@ -1121,7 +1133,6 @@ public class AppOpsService extends IAppOpsService.Stub {
        mHistoricalRegistry.systemReady(mContext.getContentResolver());

        IntentFilter packageUpdateFilter = new IntentFilter();
        packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED);
        packageUpdateFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        packageUpdateFilter.addAction(ACTION_PACKAGE_REMOVED);
        packageUpdateFilter.addDataScheme("package");
@@ -1236,7 +1247,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                }

                trimUidStatesLocked(knownUids, packageStates);
                mUidStatesInitialized = true;
            }
        }
    }
@@ -7182,12 +7192,13 @@ public class AppOpsService extends IAppOpsService.Stub {
                                }
                            }
                        }
                        synchronized (this) {
                        synchronized (AppOpsService.this) {
                            int numPkgs = mRarelyUsedPackages.size();
                            for (int i = 0; i < numPkgs; i++) {
                                candidates.add(mRarelyUsedPackages.valueAt(i));
                            }
                            mRarelyUsedPackages = candidates;
                            mRarelyUsedPackagesInitialized = true;
                        }
                    }
                });
@@ -7495,6 +7506,15 @@ public class AppOpsService extends IAppOpsService.Stub {

            return number;
        }

        @Override
        public void onPackageAdded(String pkgName, int appId) {
            int[] userIds = AppOpsService.this.getUserManagerInternal().getUserIds();
            for (int i = 0; i < userIds.length; i++) {
                int userId = userIds[i];
                AppOpsService.this.onPackageAdded(pkgName, UserHandle.getUid(userId, appId));
            }
        }
    }

    /**
+2 −0
Original line number Diff line number Diff line
@@ -1358,6 +1358,8 @@ final class InstallPackageHelper {
            Map<String, Boolean> createdAppId, boolean success) {
        if (success) {
            for (InstallRequest request : requests) {
                mInjector.getAppOpsManagerInternal().onPackageAdded(
                        request.getName(), request.getAppId());
                if (request.getDataLoaderType() != DataLoaderType.INCREMENTAL) {
                    continue;
                }
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.annotation.WorkerThread;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.AppOpsManagerInternal;
import android.app.ApplicationExitInfo;
import android.app.ApplicationPackageManager;
import android.app.BroadcastOptions;
@@ -1690,6 +1691,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),
                (i, pm) -> PermissionManagerService.create(context,
                        i.getSystemConfig().getAvailableFeatures()),
                (i, pm) -> LocalServices.getService(AppOpsManagerInternal.class),
                (i, pm) -> new UserManagerService(context, pm,
                        new UserDataPreparer(installer, installLock, context), lock),
                (i, pm) -> new Settings(Environment.getDataDirectory(),
+8 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.pm;

import android.app.ActivityManagerInternal;
import android.app.AppOpsManagerInternal;
import android.app.backup.IBackupManager;
import android.content.ComponentName;
import android.content.Context;
@@ -96,6 +97,7 @@ public class PackageManagerServiceInjector {
            mComponentResolverProducer;
    private final Singleton<PermissionManagerServiceInternal>
            mPermissionManagerServiceProducer;
    private final Singleton<AppOpsManagerInternal> mAppOpsManagerInternalProducer;
    private final Singleton<UserManagerService>
            mUserManagerProducer;
    private final Singleton<Settings> mSettingsProducer;
@@ -149,6 +151,7 @@ public class PackageManagerServiceInjector {
            List<ScanPartition> systemPartitions,
            Producer<ComponentResolver> componentResolverProducer,
            Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer,
            Producer<AppOpsManagerInternal> appOpsManagerInternalProducer,
            Producer<UserManagerService> userManagerProducer,
            Producer<Settings> settingsProducer,
            Producer<AppsFilterImpl> appsFilterProducer,
@@ -194,6 +197,7 @@ public class PackageManagerServiceInjector {
                componentResolverProducer);
        mPermissionManagerServiceProducer = new Singleton<>(
                permissionManagerServiceProducer);
        mAppOpsManagerInternalProducer = new Singleton<>(appOpsManagerInternalProducer);
        mUserManagerProducer = new Singleton<>(userManagerProducer);
        mSettingsProducer = new Singleton<>(settingsProducer);
        mAppsFilterProducer = new Singleton<>(appsFilterProducer);
@@ -290,6 +294,10 @@ public class PackageManagerServiceInjector {
        return mPermissionManagerServiceProducer.get(this, mPackageManager);
    }

    public AppOpsManagerInternal getAppOpsManagerInternal() {
        return mAppOpsManagerInternalProducer.get(this, mPackageManager);
    }

    public Context getContext() {
        return mContext;
    }
Loading