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

Commit 37dc1932 authored by Lee Shombert's avatar Lee Shombert
Browse files

Normalize findPreferredActivityNotLocked()

Bug: 187080582

This change modifies PackageManagerService in preparation for moving
findPreferredActivityNotLocked() into Computer.  The synchronized
block in findPreferredActivityNotLocked() is pulled into its own
function to comply with Computer rules.  Two functions that are needed
by findPreferredActivityNotLocked() are made static so they can be
referenced from inside ComputerEngine.  Note that because the
functions can be made static, they do not depend on the PM snapshot.

Some calls from findPreferredActivityNotLocked() that used to be
outside the PM lock are now inside the PM lock.

A few legacy lint errors are corrected.

Test: atest
 * CtsContentTestCases:IntentFilterTest
 * CtsDynamicMimeHostTestCases
 * CtsRoleTestCases
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:ScanTests
 * UserLifecycleTests#startUser
 * UserLifecycleTests#stopUser
 * UserLifecycleTests#switchUser
 * FrameworksServicesTests:WatcherTest
 * android.appsecurity.cts.EphemeralTest
 * android.appsecurity.cts.InstantAppUserTest
Change-Id: Ib977ea97d06a5eaf02080272f25e8f6139406e7d
parent 7113328b
Loading
Loading
Loading
Loading
+226 −180
Original line number Diff line number Diff line
@@ -9068,7 +9068,7 @@ public class PackageManagerService extends IPackageManager.Stub
    /**
     * Update given intent when being used to request {@link ResolveInfo}.
     */
    private Intent updateIntentForResolve(Intent intent) {
    private static Intent updateIntentForResolve(Intent intent) {
        if (intent.getSelector() != null) {
            intent = intent.getSelector();
        }
@@ -10411,12 +10411,15 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    @GuardedBy("mLock")
    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
    private ResolveInfo findPersistentPreferredActivityLP(Intent intent,
            String resolvedType,
            int flags, List<ResolveInfo> query, boolean debug, int userId) {
        final int N = query.size();
        PersistentPreferredIntentResolver ppir = mSettings.getPersistentPreferredActivities(userId);
        // Get the list of persistent preferred activities that handle the intent
        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
        if (DEBUG_PREFERRED || debug) {
            Slog.v(TAG, "Looking for persistent preferred activities...");
        }
        List<PersistentPreferredActivity> pprefs = ppir != null
                ? ppir.queryIntent(intent, resolvedType,
                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
@@ -10458,8 +10461,8 @@ public class PackageManagerService extends IPackageManager.Stub
                    }
                    //  Found a persistent preference that can handle the intent.
                    if (DEBUG_PREFERRED || debug) {
                        Slog.v(TAG, "Returning persistent preferred activity: " +
                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
                        Slog.v(TAG, "Returning persistent preferred activity: "
                                + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
                    }
                    return ri;
                }
@@ -10468,50 +10471,42 @@ public class PackageManagerService extends IPackageManager.Stub
        return null;
    }
    private boolean isHomeIntent(Intent intent) {
    private static boolean isHomeIntent(Intent intent) {
        return ACTION_MAIN.equals(intent.getAction())
                && intent.hasCategory(CATEGORY_HOME)
                && intent.hasCategory(CATEGORY_DEFAULT);
    }
    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId) {
        return findPreferredActivityNotLocked(
                intent, resolvedType, flags, query, always, removeMatches, debug, userId,
                UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
    // findPreferredActivityBody returns two items: a "things changed" flag and a
    // ResolveInfo, which is the preferred activity itself.
    private static class FindPreferredActivityBodyResult {
        boolean mChanged;
        ResolveInfo mPreferredResolveInfo;
    }
    // TODO: handle preferred activities missing while user has amnesia
    /** <b>must not hold {@link #mLock}</b> */
    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
    // The body of findPreferredActivity.
    private FindPreferredActivityBodyResult findPreferredActivityBody(
            Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        // Do NOT hold the packages lock; this calls up into the settings provider which
        // could cause a deadlock.
        final boolean isDeviceProvisioned =
                android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                        android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered,
            int callingUid, boolean isDeviceProvisioned) {
        synchronized (mLock) {
            FindPreferredActivityBodyResult result = new FindPreferredActivityBodyResult();
            flags = updateFlagsForResolve(
                    flags, userId, callingUid, false /*includeInstantApps*/,
                isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
                        flags));
                    isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
                            resolvedType, flags));
            intent = updateIntentForResolve(intent);
        // writer
        synchronized (mLock) {
            // Try to find a matching persistent preferred activity.
            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
                    debug, userId);
            result.mPreferredResolveInfo = findPersistentPreferredActivityLP(intent,
                    resolvedType, flags, query, debug, userId);
            // If a persistent preferred activity matched, use it.
            if (pri != null) {
                return pri;
            if (result.mPreferredResolveInfo != null) {
                return result;
            }
            PreferredIntentResolver pir = mSettings.getPreferredActivities(userId);
@@ -10523,8 +10518,7 @@ public class PackageManagerService extends IPackageManager.Stub
                            userId)
                    : null;
            if (prefs != null && prefs.size() > 0) {
                boolean changed = false;
                try {
                // First figure out how good the original match set is.
                // We will only allow preferred activities that came
                // from the same match quality.
@@ -10535,16 +10529,18 @@ public class PackageManagerService extends IPackageManager.Stub
                final int N = query.size();
                for (int j = 0; j < N; j++) {
                    final ResolveInfo ri = query.get(j);
                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
                    if (DEBUG_PREFERRED || debug) {
                        Slog.v(TAG, "Match for " + ri.activityInfo
                                + ": 0x" + Integer.toHexString(match));
                    }
                    if (ri.match > match) {
                        match = ri.match;
                    }
                }
                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
                            + Integer.toHexString(match));
                if (DEBUG_PREFERRED || debug) {
                    Slog.v(TAG, "Best match: 0x" + Integer.toHexString(match));
                }
                match &= IntentFilter.MATCH_CATEGORY_MASK;
                final int M = prefs.size();
                for (int i = 0; i < M; i++) {
@@ -10556,8 +10552,10 @@ public class PackageManagerService extends IPackageManager.Stub
                        pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
                    }
                    if (pa.mPref.mMatch != match) {
                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
                        if (DEBUG_PREFERRED || debug) {
                            Slog.v(TAG, "Skipping bad match "
                                    + Integer.toHexString(pa.mPref.mMatch));
                        }
                        continue;
                    }
                    // If it's not an "always" type preferred activity and that's what we're
@@ -10597,7 +10595,7 @@ public class PackageManagerService extends IPackageManager.Stub
                        Slog.w(TAG, "Removing dangling preferred activity: "
                                + pa.mPref.mComponent);
                        pir.removeFilter(pa);
                            changed = true;
                        result.mChanged = true;
                        continue;
                    }
                    for (int j = 0; j < N; j++) {
@@ -10612,7 +10610,7 @@ public class PackageManagerService extends IPackageManager.Stub
                        if (removeMatches && allowSetMutation) {
                            pir.removeFilter(pa);
                                changed = true;
                            result.mChanged = true;
                            if (DEBUG_PREFERRED) {
                                Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
                            }
@@ -10645,7 +10643,7 @@ public class PackageManagerService extends IPackageManager.Stub
                                            pa.mPref.mAlways);
                                    pir.removeFilter(pa);
                                    pir.addFilter(freshPa);
                                        changed = true;
                                    result.mChanged = true;
                                } else {
                                    if (DEBUG_PREFERRED) {
                                        Slog.i(TAG, "Do not remove preferred activity");
@@ -10668,30 +10666,78 @@ public class PackageManagerService extends IPackageManager.Stub
                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
                                            false);
                                    pir.addFilter(lastChosen);
                                        changed = true;
                                    result.mChanged = true;
                                }
                                    return null;
                                result.mPreferredResolveInfo = null;
                                return result;
                            }
                        }
                        // Yay! Either the set matched or we're looking for the last chosen
                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
                        if (DEBUG_PREFERRED || debug) {
                            Slog.v(TAG, "Returning preferred activity: "
                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
                            return ri;
                        }
                        result.mPreferredResolveInfo = ri;
                        return result;
                    }
                }
                } finally {
                    if (changed) {
            }
            return result;
        }
    }
    private FindPreferredActivityBodyResult findPreferredActivityInternal(
            Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
        final int callingUid = Binder.getCallingUid();
        // Do NOT hold the packages lock; this calls up into the settings provider which
        // could cause a deadlock.
        final boolean isDeviceProvisioned =
                android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                        android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
        // Find the preferred activity - the lock is held inside the method.
        return findPreferredActivityBody(
                intent, resolvedType, flags, query, always, removeMatches, debug,
                userId, queryMayBeFiltered, callingUid, isDeviceProvisioned);
    }
    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId) {
        return findPreferredActivityNotLocked(
                intent, resolvedType, flags, query, always, removeMatches, debug, userId,
                UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
    }
    // TODO: handle preferred activities missing while user has amnesia
    /** <b>must not hold {@link #mLock}</b> */
    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, boolean always,
            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        if (!mUserManager.exists(userId)) return null;
        FindPreferredActivityBodyResult body = findPreferredActivityInternal(
                intent, resolvedType, flags, query, always,
                removeMatches, debug, userId, queryMayBeFiltered);
        if (body.mChanged) {
            if (DEBUG_PREFERRED) {
                Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
            }
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
        if ((DEBUG_PREFERRED || debug) && body.mPreferredResolveInfo == null) {
            Slog.v(TAG, "No preferred activity to return");
        }
        }
        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
        return null;
        return body.mPreferredResolveInfo;
    }
    /*