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

Commit 19531b91 authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge "Support launching apps by package name without visibility"

parents 2838d83f 6dc1bd35
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12535,6 +12535,7 @@ package android.content.pm {
    method public abstract int getInstantAppCookieMaxBytes();
    method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method @Nullable public abstract android.content.Intent getLaunchIntentForPackage(@NonNull String);
    method @NonNull public android.content.IntentSender getLaunchIntentSenderForPackage(@NonNull String);
    method @Nullable public abstract android.content.Intent getLeanbackLaunchIntentForPackage(@NonNull String);
    method @NonNull public java.util.Set<java.lang.String> getMimeGroup(@NonNull String);
    method @NonNull public android.content.pm.ModuleInfo getModuleInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+10 −0
Original line number Diff line number Diff line
@@ -312,6 +312,16 @@ public class ApplicationPackageManager extends PackageManager {
        return intent;
    }

    @Override
    public @NonNull IntentSender getLaunchIntentSenderForPackage(@NonNull String packageName) {
        try {
            return mPM.getLaunchIntentSenderForPackage(packageName, mContext.getPackageName(),
                    mContext.getAttributionTag(), getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public int[] getPackageGids(String packageName) throws NameNotFoundException {
        return getPackageGids(packageName, 0);
+3 −0
Original line number Diff line number Diff line
@@ -757,6 +757,9 @@ interface IPackageManager {

    void requestChecksums(in String packageName, boolean includeSplits, int optional, int required, in List trustedInstallers, in IOnChecksumsReadyListener onChecksumsReadyListener, int userId);

    IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
                String featureId, int userId);

    //------------------------------------------------------------------------
    //
    // The following binder interfaces have been moved to IPermissionManager
+27 −0
Original line number Diff line number Diff line
@@ -4522,12 +4522,17 @@ public abstract class PackageManager {
     * main activity in the category {@link Intent#CATEGORY_LAUNCHER}. Returns
     * <code>null</code> if neither are found.
     *
     * <p>Consider using {@link #getLaunchIntentSenderForPackage(String)} if
     * the caller is not allowed to query for the <code>packageName</code>.
     *
     * @param packageName The name of the package to inspect.
     *
     * @return A fully-qualified {@link Intent} that can be used to launch the
     * main activity in the package. Returns <code>null</code> if the package
     * does not contain such an activity, or if <em>packageName</em> is not
     * recognized.
     *
     * @see #getLaunchIntentSenderForPackage(String)
     */
    public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName);

@@ -4561,6 +4566,28 @@ public abstract class PackageManager {
    @SuppressWarnings("HiddenAbstractMethod")
    public abstract @Nullable Intent getCarLaunchIntentForPackage(@NonNull String packageName);

    /**
     * Returns an {@link IntentSender} that can be used to launch a front-door activity in a
     * package. This is used, for example, to implement an "open" button when browsing through
     * packages. The current implementation is the same with
     * {@link #getLaunchIntentForPackage(String)}. Instead of returning the {@link Intent}, it
     * returns the {@link IntentSender} which is not restricted by the package visibility.
     *
     * <p>The caller can invoke
     * {@link IntentSender#sendIntent(Context, int, Intent, IntentSender.OnFinished, Handler)}
     * to launch the activity. An {@link IntentSender.SendIntentException} is thrown if the
     * package does not contain such an activity, or if <em>packageName</em> is not recognized.
     *
     * @param packageName The name of the package to inspect.
     * @return Returns a {@link IntentSender} to launch the activity.
     *
     * @see #getLaunchIntentForPackage(String)
     */
    public @NonNull IntentSender getLaunchIntentSenderForPackage(@NonNull String packageName) {
        throw new UnsupportedOperationException("getLaunchIntentSenderForPackage not implemented"
                + "in subclass");
    }

    /**
     * Return an array of all of the POSIX secondary group IDs that have been
     * assigned to the given package.
+52 −0
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ import android.app.AppOpsManager;
import android.app.ApplicationPackageManager;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.PendingIntent;
import android.app.ResourcesManager;
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SecurityLog;
@@ -161,6 +162,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
@@ -28014,6 +28016,56 @@ public class PackageManagerService extends IPackageManager.Stub
            }
        }
    }
    @Override
    public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
            String featureId, int userId) throws RemoteException {
        Objects.requireNonNull(packageName);
        final int callingUid = Binder.getCallingUid();
        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
                false /* checkShell */, "get launch intent sender for package");
        final int packageUid = getPackageUid(callingPackage, 0 /* flags */, userId);
        if (!UserHandle.isSameApp(callingUid, packageUid)) {
            throw new SecurityException("getLaunchIntentSenderForPackage() from calling uid: "
                    + callingUid + " does not own package: " + callingPackage);
        }
        // Using the same implementation with the #getLaunchIntentForPackage to get the ResolveInfo.
        // Pass the resolveForStart as true in queryIntentActivities to skip the app filtering.
        final Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
        intentToResolve.addCategory(Intent.CATEGORY_INFO);
        intentToResolve.setPackage(packageName);
        String resolvedType = intentToResolve.resolveTypeIfNeeded(mContext.getContentResolver());
        List<ResolveInfo> ris = queryIntentActivitiesInternal(intentToResolve, resolvedType,
                0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
                true /* resolveForStart */, false /* allowDynamicSplits */);
        if (ris == null || ris.size() <= 0) {
            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
            intentToResolve.setPackage(packageName);
            resolvedType = intentToResolve.resolveTypeIfNeeded(mContext.getContentResolver());
            ris = queryIntentActivitiesInternal(intentToResolve, resolvedType,
                    0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
                    true /* resolveForStart */, false /* allowDynamicSplits */);
        }
        final Intent intent = new Intent(intentToResolve);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // For the case of empty result, no component name is assigned into the intent. A
        // non-launchable IntentSender which contains the failed intent is created. The
        // SendIntentException is thrown if the IntentSender#sendIntent is invoked.
        if (ris != null && !ris.isEmpty()) {
            intent.setClassName(ris.get(0).activityInfo.packageName,
                    ris.get(0).activityInfo.name);
        }
        final IIntentSender target = ActivityManager.getService().getIntentSenderWithFeature(
                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                featureId, null /* token */, null /* resultWho */,
                1 /* requestCode */, new Intent[] { intent },
                resolvedType != null ? new String[] { resolvedType } : null,
                PendingIntent.FLAG_IMMUTABLE, null /* bOptions */, userId);
        return new IntentSender(target);
    }
}
interface PackageSender {