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

Commit 2ad8a174 authored by Pinyao Ting's avatar Pinyao Ting
Browse files

Parse share-targets defined by non-main activities

Some system apps do not have any launcher icons but want to publish
sharing shortcuts. As a fix, non-exported main activites from system
apps are parsed for their XML resource.

Bug: 136353429
Test: Manual test
Change-Id: I2a3025ba148435ed48e2e69d4daed4c51f141d77
parent f8c4f8ee
Loading
Loading
Loading
Loading
+40 −20
Original line number Diff line number Diff line
@@ -256,6 +256,14 @@ public class ShortcutService extends IShortcutService.Stub {
        String KEY_ICON_FORMAT = "icon_format";
    }

    private static final int PACKAGE_MATCH_FLAGS =
            PackageManager.MATCH_DIRECT_BOOT_AWARE
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_UNINSTALLED_PACKAGES;

    private static final int SYSTEM_APP_MASK =
            ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;

    final Context mContext;

    private final Object mLock = new Object();
@@ -269,6 +277,15 @@ public class ShortcutService extends IShortcutService.Stub {
        }
    };

    private static Predicate<ResolveInfo> ACTIVITY_NOT_SYSTEM_NOR_ENABLED = (ri) -> {
        final ApplicationInfo ai = ri.activityInfo.applicationInfo;
        final boolean isSystemApp = ai != null && (ai.flags & SYSTEM_APP_MASK) != 0;
        return !isSystemApp && !ri.activityInfo.enabled;
    };

    private static Predicate<ResolveInfo> ACTIVITY_NOT_INSTALLED = (ri) ->
            !isInstalled(ri.activityInfo);

    // Temporarily reverted to anonymous inner class form due to: b/32554459
    private static Predicate<PackageInfo> PACKAGE_NOT_INSTALLED = new Predicate<PackageInfo>() {
        public boolean test(PackageInfo pi) {
@@ -350,11 +367,6 @@ public class ShortcutService extends IShortcutService.Stub {

    private final AtomicBoolean mBootCompleted = new AtomicBoolean();

    private static final int PACKAGE_MATCH_FLAGS =
            PackageManager.MATCH_DIRECT_BOOT_AWARE
                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_UNINSTALLED_PACKAGES;

    /**
     * Note we use a fine-grained lock for {@link #mUnlockedUsers} due to b/64303666.
     */
@@ -3599,7 +3611,7 @@ public class ShortcutService extends IShortcutService.Stub {
        final long token = injectClearCallingIdentity();
        try {
            return mIPackageManager.getPackageInfo(
                    packageName, PACKAGE_MATCH_FLAGS
                    packageName, PACKAGE_MATCH_FLAGS | PackageManager.MATCH_DISABLED_COMPONENTS
                            | (getSignatures ? PackageManager.GET_SIGNING_CERTIFICATES : 0),
                    userId);
        } catch (RemoteException e) {
@@ -3634,7 +3646,8 @@ public class ShortcutService extends IShortcutService.Stub {
        final long start = getStatStartTime();
        final long token = injectClearCallingIdentity();
        try {
            return mIPackageManager.getApplicationInfo(packageName, PACKAGE_MATCH_FLAGS, userId);
            return mIPackageManager.getApplicationInfo(packageName,
                    PACKAGE_MATCH_FLAGS | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
        } catch (RemoteException e) {
            // Shouldn't happen.
            Slog.wtf(TAG, "RemoteException", e);
@@ -3665,8 +3678,9 @@ public class ShortcutService extends IShortcutService.Stub {
        final long start = getStatStartTime();
        final long token = injectClearCallingIdentity();
        try {
            return mIPackageManager.getActivityInfo(activity,
                    (PACKAGE_MATCH_FLAGS | PackageManager.GET_META_DATA), userId);
            return mIPackageManager.getActivityInfo(activity, (PACKAGE_MATCH_FLAGS
                    | PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_META_DATA),
                    userId);
        } catch (RemoteException e) {
            // Shouldn't happen.
            Slog.wtf(TAG, "RemoteException", e);
@@ -3711,7 +3725,8 @@ public class ShortcutService extends IShortcutService.Stub {
    List<PackageInfo> injectGetPackagesWithUninstalled(@UserIdInt int userId)
            throws RemoteException {
        final ParceledListSlice<PackageInfo> parceledList =
                mIPackageManager.getInstalledPackages(PACKAGE_MATCH_FLAGS, userId);
                mIPackageManager.getInstalledPackages(
                        PACKAGE_MATCH_FLAGS | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
        if (parceledList == null) {
            return Collections.emptyList();
        }
@@ -3810,6 +3825,12 @@ public class ShortcutService extends IShortcutService.Stub {
        return intent;
    }

    private static boolean isSystemApp(@Nullable final ApplicationInfo ai) {
        final int systemAppMask =
                ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
        return ai != null && ((ai.flags & systemAppMask) != 0);
    }

    /**
     * Same as queryIntentActivitiesAsUser, except it makes sure the package is installed,
     * and only returns exported activities.
@@ -3832,9 +3853,8 @@ public class ShortcutService extends IShortcutService.Stub {
        final List<ResolveInfo> resolved;
        final long token = injectClearCallingIdentity();
        try {
            resolved =
                    mContext.getPackageManager().queryIntentActivitiesAsUser(
                            intent, PACKAGE_MATCH_FLAGS, userId);
            resolved = mContext.getPackageManager().queryIntentActivitiesAsUser(intent,
                    PACKAGE_MATCH_FLAGS | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
        } finally {
            injectRestoreCallingIdentity(token);
        }
@@ -3842,9 +3862,8 @@ public class ShortcutService extends IShortcutService.Stub {
            return EMPTY_RESOLVE_INFO;
        }
        // Make sure the package is installed.
        if (!isInstalled(resolved.get(0).activityInfo)) {
            return EMPTY_RESOLVE_INFO;
        }
        resolved.removeIf(ACTIVITY_NOT_INSTALLED);
        resolved.removeIf(ACTIVITY_NOT_SYSTEM_NOR_ENABLED);
        if (exportedOnly) {
            resolved.removeIf(ACTIVITY_NOT_EXPORTED);
        }
@@ -3852,8 +3871,8 @@ public class ShortcutService extends IShortcutService.Stub {
    }

    /**
     * Return the main activity that is enabled and exported.  If multiple activities are found,
     * return the first one.
     * Return the main activity that is exported and, for non-system apps, enabled.  If multiple
     * activities are found, return the first one.
     */
    @Nullable
    ComponentName injectGetDefaultMainActivity(@NonNull String packageName, int userId) {
@@ -3868,7 +3887,7 @@ public class ShortcutService extends IShortcutService.Stub {
    }

    /**
     * Return whether an activity is enabled, exported and main.
     * Return whether an activity is main, exported and, for non-system apps, enabled.
     */
    boolean injectIsMainActivity(@NonNull ComponentName activity, int userId) {
        final long start = getStatStartTime();
@@ -3902,7 +3921,8 @@ public class ShortcutService extends IShortcutService.Stub {
    }

    /**
     * Return all the enabled, exported and main activities from a package.
     * Return all the main activities that are exported and, for non-system apps, enabled, from a
     * package.
     */
    @NonNull
    List<ResolveInfo> injectGetMainActivities(@NonNull String packageName, int userId) {