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

Commit 01dccd0d authored by Makoto Onuki's avatar Makoto Onuki Committed by The Android Automerger
Browse files

Start shortcuts as if publisher apps did using PendingIntent

Bug 29639471

Change-Id: I2aad115669b431cbea785ba92040b1958117ab47
parent ba1e3d60
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -19,7 +19,9 @@ package android.app;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.IIntentSender;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IBinder;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.IVoiceInteractionSession;


@@ -161,4 +163,11 @@ public abstract class ActivityManagerInternal {
     */
     */
    public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values,
    public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values,
            int userId);
            int userId);

    /**
     * Create an {@link IIntentSender} to start an activity, as if {@code packageName} on
     * user {@code userId} created it.
     */
    public abstract IIntentSender getActivityIntentSenderAsPackage(String packageName,
            int userId, int requestCode, Intent intent, int flags, Bundle bOptions);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -51,7 +51,7 @@ interface ILauncherApps {
            in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user);
            in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user);
    void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
    void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
            in UserHandle user);
            in UserHandle user);
    boolean startShortcut(String callingPackage, String packageName, String id,
    void startShortcut(String callingPackage, String packageName, String id,
            in Rect sourceBounds, in Bundle startActivityOptions, int userId);
            in Rect sourceBounds, in Bundle startActivityOptions, int userId);


    int getShortcutIconResId(String callingPackage, String packageName, String id,
    int getShortcutIconResId(String callingPackage, String packageName, String id,
+27 −0
Original line number Original line Diff line number Diff line
@@ -21663,6 +21663,33 @@ public final class ActivityManagerService extends ActivityManagerNative
                updateConfigurationLocked(values, null, false, true, userId);
                updateConfigurationLocked(values, null, false, true, userId);
            }
            }
        }
        }
        @Override
        public IIntentSender getActivityIntentSenderAsPackage(
                String packageName, int userId, int requestCode, Intent intent,
                int flags, Bundle bOptions) {
            String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                    mContext.getContentResolver()) : null;
            // UID of the package on user userId.
            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
            // packageUid may not be initialized.
            int packageUid = 0;
            try {
                packageUid = AppGlobals.getPackageManager().getPackageUid(
                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
            } catch (RemoteException e) {
                // Shouldn't happen.
            }
            synchronized (ActivityManagerService.this) {
                return getIntentSenderLocked(
                        ActivityManager.INTENT_SENDER_ACTIVITY, packageName, packageUid,
                        UserHandle.getUserId(packageUid), /*token*/ null, /*resultWho*/ null,
                        requestCode, new Intent[] {intent}, new String[]{resolvedType},
                        flags, bOptions);
            }
        }
    }
    }
    private final class SleepTokenImpl extends SleepToken {
    private final class SleepTokenImpl extends SleepToken {
+35 −8
Original line number Original line Diff line number Diff line
@@ -19,9 +19,13 @@ package com.android.server.pm;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.AppGlobals;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
@@ -98,6 +102,7 @@ public class LauncherAppsService extends SystemService {
        private final Context mContext;
        private final Context mContext;
        private final PackageManager mPm;
        private final PackageManager mPm;
        private final UserManager mUm;
        private final UserManager mUm;
        private final ActivityManagerInternal mActivityManagerInternal;
        private final ShortcutServiceInternal mShortcutServiceInternal;
        private final ShortcutServiceInternal mShortcutServiceInternal;
        private final PackageCallbackList<IOnAppsChangedListener> mListeners
        private final PackageCallbackList<IOnAppsChangedListener> mListeners
                = new PackageCallbackList<IOnAppsChangedListener>();
                = new PackageCallbackList<IOnAppsChangedListener>();
@@ -110,6 +115,8 @@ public class LauncherAppsService extends SystemService {
            mContext = context;
            mContext = context;
            mPm = mContext.getPackageManager();
            mPm = mContext.getPackageManager();
            mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
            mActivityManagerInternal = Preconditions.checkNotNull(
                    LocalServices.getService(ActivityManagerInternal.class));
            mShortcutServiceInternal = Preconditions.checkNotNull(
            mShortcutServiceInternal = Preconditions.checkNotNull(
                    LocalServices.getService(ShortcutServiceInternal.class));
                    LocalServices.getService(ShortcutServiceInternal.class));
            mShortcutServiceInternal.addListener(mPackageMonitor);
            mShortcutServiceInternal.addListener(mPackageMonitor);
@@ -432,7 +439,7 @@ public class LauncherAppsService extends SystemService {
        }
        }


        @Override
        @Override
        public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
        public void startShortcut(String callingPackage, String packageName, String shortcutId,
                Rect sourceBounds, Bundle startActivityOptions, int userId) {
                Rect sourceBounds, Bundle startActivityOptions, int userId) {
            verifyCallingPackage(callingPackage);
            verifyCallingPackage(callingPackage);
            ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId);
            ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId);
@@ -451,20 +458,40 @@ public class LauncherAppsService extends SystemService {
            final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(),
            final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(),
                    callingPackage, packageName, shortcutId, userId);
                    callingPackage, packageName, shortcutId, userId);
            if (intent == null) {
            if (intent == null) {
                return false;
                return;
            }
            }
            // Note the target activity doesn't have to be exported.
            // Note the target activity doesn't have to be exported.


            intent.setSourceBounds(sourceBounds);
            prepareIntentForLaunch(intent, sourceBounds);
            prepareIntentForLaunch(intent, sourceBounds);


            startShortcutIntentAsPublisher(
                    intent, packageName, startActivityOptions, userId);
        }

        @VisibleForTesting
        protected void startShortcutIntentAsPublisher(@NonNull Intent intent,
                @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {

            try {
                final IIntentSender intentSender;

                final long ident = Binder.clearCallingIdentity();
                final long ident = Binder.clearCallingIdentity();
                try {
                try {
                mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId));
                    intentSender = mActivityManagerInternal.getActivityIntentSenderAsPackage(
                            publisherPackage, userId, /* requestCode= */ 0,
                            intent, PendingIntent.FLAG_ONE_SHOT,
                            /* options= */ startActivityOptions);
                } finally {
                } finally {
                    Binder.restoreCallingIdentity(ident);
                    Binder.restoreCallingIdentity(ident);
                }
                }
            return true;

                // Negative result means a failure.
                ActivityManagerNative.getDefault().sendIntentSender(
                        intentSender, 0, null, null, null, null, null);

            } catch (RemoteException e) {
                return;
            }
        }
        }


        @Override
        @Override
+12 −0
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.Activity;
import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
@@ -466,6 +467,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        void injectRestoreCallingIdentity(long token) {
        void injectRestoreCallingIdentity(long token) {
            mInjectedCallingUid = (int) token;
            mInjectedCallingUid = (int) token;
        }
        }

        @Override
        protected void startShortcutIntentAsPublisher(@NonNull Intent intent,
                @NonNull String publisherPackage, Bundle startActivityOptions, int userId) {
            // Just forward to startActivityAsUser() during unit tests.
            mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId));
        }
    }
    }


    protected class LauncherAppsTestable extends LauncherApps {
    protected class LauncherAppsTestable extends LauncherApps {
@@ -518,6 +526,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
    protected PackageManagerInternal mMockPackageManagerInternal;
    protected PackageManagerInternal mMockPackageManagerInternal;
    protected UserManager mMockUserManager;
    protected UserManager mMockUserManager;
    protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
    protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
    protected ActivityManagerInternal mMockActivityManagerInternal;


    protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
    protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
    protected static final int CALLING_UID_1 = 10001;
    protected static final int CALLING_UID_1 = 10001;
@@ -616,11 +625,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        mMockPackageManagerInternal = mock(PackageManagerInternal.class);
        mMockPackageManagerInternal = mock(PackageManagerInternal.class);
        mMockUserManager = mock(UserManager.class);
        mMockUserManager = mock(UserManager.class);
        mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
        mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
        mMockActivityManagerInternal = mock(ActivityManagerInternal.class);


        LocalServices.removeServiceForTest(PackageManagerInternal.class);
        LocalServices.removeServiceForTest(PackageManagerInternal.class);
        LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
        LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
        LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
        LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
        LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal);
        LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal);
        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
        LocalServices.addService(ActivityManagerInternal.class, mMockActivityManagerInternal);


        // Prepare injection values.
        // Prepare injection values.