diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index 2af1bcb..3060840 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -16,6 +16,7 @@
 package com.android.server.pm;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.pm.PackageInfo;
 import android.content.pm.ShortcutInfo;
@@ -103,6 +104,9 @@
         // Nothing to do.
     }
 
+    /**
+     * Pin the given shortcuts, replacing the current pinned ones.
+     */
     public void pinShortcuts(@UserIdInt int packageUserId,
             @NonNull String packageName, @NonNull List<String> ids) {
         final ShortcutPackage packageShortcuts =
@@ -143,11 +147,39 @@
     /**
      * Return the pinned shortcut IDs for the publisher package.
      */
+    @Nullable
     public ArraySet<String> getPinnedShortcutIds(@NonNull String packageName,
             @UserIdInt int packageUserId) {
         return mPinnedShortcuts.get(PackageWithUser.of(packageUserId, packageName));
     }
 
+    /**
+     * Return true if the given shortcut is pinned by this launcher.
+     */
+    public boolean hasPinned(ShortcutInfo shortcut) {
+        final ArraySet<String> pinned =
+                getPinnedShortcutIds(shortcut.getPackage(), shortcut.getUserId());
+        return (pinned != null) && pinned.contains(shortcut.getId());
+    }
+
+    /**
+     * Additionally pin a shortcut. c.f. {@link #pinShortcuts(int, String, List)}
+     */
+    public void addPinnedShortcut(@NonNull String packageName, @UserIdInt int packageUserId,
+            String id) {
+        final ArraySet<String> pinnedSet = getPinnedShortcutIds(packageName, packageUserId);
+        final ArrayList<String> pinnedList;
+        if (pinnedSet != null) {
+            pinnedList = new ArrayList<>(pinnedSet.size() + 1);
+            pinnedList.addAll(pinnedSet);
+        } else {
+            pinnedList = new ArrayList<>(1);
+        }
+        pinnedList.add(id);
+
+        pinShortcuts(packageUserId, packageName, pinnedList);
+    }
+
     boolean cleanUpPackage(String packageName, @UserIdInt int packageUserId) {
         return mPinnedShortcuts.remove(PackageWithUser.of(packageUserId, packageName)) != null;
     }
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 2eb0778..b745062 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -179,7 +179,7 @@
         }
     }
 
-    private void ensureNotImmutable(@NonNull String id) {
+    public void ensureNotImmutable(@NonNull String id) {
         ensureNotImmutable(mShortcuts.get(id));
     }
 
@@ -706,6 +706,7 @@
             for (int i = mShortcuts.size() - 1; i >= 0; i--) {
                 final ShortcutInfo si = mShortcuts.valueAt(i);
 
+                // Disable dynamic shortcuts whose target activity is gone.
                 if (si.isDynamic()) {
                     if (!s.injectIsMainActivity(si.getActivity(), getPackageUserId())) {
                         Slog.w(TAG, String.format(
diff --git a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
new file mode 100644
index 0000000..7928257
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.IPinItemRequest;
+import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.PinItemRequest;
+import android.content.pm.ShortcutInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
+
+/**
+ * Handles {@link android.content.pm.ShortcutManager#requestPinShortcut} related tasks.
+ */
+class ShortcutRequestPinProcessor {
+    private static final String TAG = ShortcutService.TAG;
+    private static final boolean DEBUG = ShortcutService.DEBUG;
+
+    private final ShortcutService mService;
+    private final Object mLock;
+
+    /**
+     * Internal for {@link android.content.pm.LauncherApps.PinItemRequest} which receives callbacks.
+     */
+    private static class PinShortcutRequestInner extends IPinItemRequest.Stub {
+        private final ShortcutRequestPinProcessor mProcessor;
+        public final ShortcutInfo shortcut;
+        private final IntentSender mResultIntent;
+
+        public final String launcherPackage;
+        public final int launcherUserId;
+        public final boolean preExisting;
+
+        @GuardedBy("this")
+        private boolean mAccepted;
+
+        private PinShortcutRequestInner(ShortcutRequestPinProcessor processor,
+                ShortcutInfo shortcut, IntentSender resultIntent,
+                String launcherPackage, int launcherUserId, boolean preExisting) {
+            mProcessor = processor;
+            this.shortcut = shortcut;
+            mResultIntent = resultIntent;
+            this.launcherPackage = launcherPackage;
+            this.launcherUserId = launcherUserId;
+            this.preExisting = preExisting;
+        }
+
+        @Override
+        public boolean isValid() {
+            // TODO When an app calls requestPinShortcut(), all pending requests should be
+            // invalidated.
+            synchronized (this) {
+                return !mAccepted;
+            }
+        }
+
+        /**
+         * Called when the launcher calls {@link PinItemRequest#accept}.
+         */
+        @Override
+        public boolean accept(Bundle options) {
+            // Make sure the options are unparcellable by the FW. (e.g. not containing unknown
+            // classes.)
+            if (options != null) {
+                try {
+                    options.size();
+                } catch (RuntimeException e) {
+                    throw new IllegalArgumentException("options cannot be unparceled", e);
+                }
+            }
+            synchronized (this) {
+                if (mAccepted) {
+                    throw new IllegalStateException("accept() called already");
+                }
+                mAccepted = true;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "Launcher accepted shortcut. ID=" + shortcut.getId()
+                        + " package=" + shortcut.getPackage()
+                        + " options=" + options);
+            }
+
+            // Pin it and send the result intent.
+            if (mProcessor.directPinShortcut(this)) {
+                mProcessor.sendResultIntent(mResultIntent);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    public ShortcutRequestPinProcessor(ShortcutService service, Object lock) {
+        mService = service;
+        mLock = lock;
+    }
+
+    public boolean isRequestPinnedShortcutSupported(int callingUserId) {
+        return getRequestPinShortcutConfirmationActivity(callingUserId) != null;
+    }
+
+    /**
+     * Handle {@link android.content.pm.ShortcutManager#requestPinShortcut)}.
+     */
+    public boolean requestPinShortcutLocked(ShortcutInfo inShortcut, IntentSender resultIntent) {
+
+        // First, make sure the launcher supports it.
+
+        // Find the confirmation activity in the default launcher.
+        final Pair<ComponentName, Integer> confirmActivity =
+                getRequestPinShortcutConfirmationActivity(inShortcut.getUserId());
+
+        // If the launcher doesn't support it, just return a rejected result and finish.
+        if (confirmActivity == null) {
+            Log.w(TAG, "Launcher doesn't support requestPinnedShortcut(). Shortcut not created.");
+            return false;
+        }
+
+        final ComponentName launcherComponent = confirmActivity.first;
+        final String launcherPackage = confirmActivity.first.getPackageName();
+        final int launcherUserId = confirmActivity.second;
+
+        // Make sure the launcher user is unlocked. (it's always the parent profile, so should
+        // really be unlocked here though.)
+        mService.throwIfUserLockedL(launcherUserId);
+
+        // Next, validate the incoming shortcut, etc.
+
+        final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked(
+                inShortcut.getPackage(), inShortcut.getUserId());
+
+        final ShortcutInfo existing = ps.findShortcutById(inShortcut.getId());
+        final boolean existsAlready = existing != null;
+
+        if (DEBUG) {
+            Slog.d(TAG, "requestPinnedShortcut package=" + inShortcut.getPackage()
+                    + " existsAlready=" + existsAlready
+                    + " shortcut=" + inShortcut.toInsecureString());
+        }
+
+        // This is the shortcut that'll be sent to the launcher.
+        final ShortcutInfo shortcutToSend;
+
+        if (existsAlready) {
+            validateExistingShortcut(existing);
+
+            // See if it's already pinned.
+            if (mService.getLauncherShortcutsLocked(
+                    launcherPackage, existing.getUserId(), launcherUserId).hasPinned(existing)) {
+                Log.i(TAG, "Launcher's already pinning shortcut " + existing.getId()
+                        + " for package " + existing.getPackage());
+                sendResultIntent(resultIntent);
+                return true;
+            }
+
+            // Pass a clone, not the original.
+            // Note this will remove the intent and icons.
+            shortcutToSend = existing.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+            shortcutToSend.clearFlags(ShortcutInfo.FLAG_PINNED);
+        } else {
+            // It doesn't exist, so it must have all mandatory fields.
+            mService.validateShortcutForPinRequest(inShortcut);
+
+            // Initialize the ShortcutInfo for pending approval.
+            inShortcut.resolveResourceStrings(mService.injectGetResourcesForApplicationAsUser(
+                    inShortcut.getPackage(), inShortcut.getUserId()));
+            if (DEBUG) {
+                Slog.d(TAG, "resolved shortcut=" + inShortcut.toInsecureString());
+            }
+            // TODO Remove the intent here -- don't pass shortcut intents to the launcher.
+            shortcutToSend = inShortcut;
+        }
+
+        // Create a request object.
+        final PinShortcutRequestInner inner =
+                new PinShortcutRequestInner(this, shortcutToSend, resultIntent,
+                        launcherPackage, launcherUserId, existsAlready);
+
+        final PinItemRequest outer = new PinItemRequest(PinItemRequest.REQUEST_TYPE_SHORTCUT,
+                shortcutToSend, inner);
+
+        return startRequestConfirmActivity(launcherComponent, launcherUserId, outer);
+    }
+
+    private void validateExistingShortcut(ShortcutInfo shortcutInfo) {
+        // Make sure it's enabled.
+        // (Because we can't always force enable it automatically as it may be a stale
+        // manifest shortcut.)
+        Preconditions.checkState(shortcutInfo.isEnabled(),
+                "Shortcut ID=" + shortcutInfo + " already exists but disabled.");
+
+    }
+
+    private boolean startRequestConfirmActivity(ComponentName activity, int launcherUserId,
+            PinItemRequest request) {
+        // Start the activity.
+        final Intent confirmIntent = new Intent(LauncherApps.ACTION_CONFIRM_PIN_ITEM);
+        confirmIntent.setComponent(activity);
+        confirmIntent.putExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST, request);
+        confirmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+        final long token = mService.injectClearCallingIdentity();
+        try {
+            mService.mContext.startActivityAsUser(
+                    confirmIntent, UserHandle.of(launcherUserId));
+        } catch (RuntimeException e) { // ActivityNotFoundException, etc.
+            Log.e(TAG, "Unable to start activity " + activity, e);
+            return false;
+        } finally {
+            mService.injectRestoreCallingIdentity(token);
+        }
+        return true;
+    }
+
+    /**
+     * Find the activity that handles {@link LauncherApps#ACTION_CONFIRM_PIN_ITEM} in the
+     * default launcher.
+     */
+    @Nullable
+    @VisibleForTesting
+    Pair<ComponentName, Integer> getRequestPinShortcutConfirmationActivity(
+            int callingUserId) {
+        // Find the default launcher.
+        final int launcherUserId = mService.getParentOrSelfUserId(callingUserId);
+        final ComponentName defaultLauncher = mService.getDefaultLauncher(launcherUserId);
+
+        if (defaultLauncher == null) {
+            Log.e(TAG, "Default launcher not found.");
+            return null;
+        }
+        final ComponentName activity = mService.injectGetPinConfirmationActivity(
+                defaultLauncher.getPackageName(), launcherUserId);
+        return (activity == null) ? null : Pair.create(activity, launcherUserId);
+    }
+
+    public void sendResultIntent(@Nullable IntentSender intent) {
+        if (DEBUG) {
+            Slog.d(TAG, "Sending result intent.");
+        }
+        mService.injectSendIntentSender(intent);
+    }
+
+    /**
+     * The last step of the "request pin shortcut" flow.  Called when the launcher accepted a
+     * request.
+     */
+    public boolean directPinShortcut(PinShortcutRequestInner request) {
+
+        final ShortcutInfo original = request.shortcut;
+        final int appUserId = original.getUserId();
+        final String appPackageName = original.getPackage();
+        final int launcherUserId = request.launcherUserId;
+        final String launcherPackage = request.launcherPackage;
+        final String shortcutId = original.getId();
+
+        synchronized (mLock) {
+            if (!(mService.isUserUnlockedL(appUserId)
+                    && mService.isUserUnlockedL(request.launcherUserId))) {
+                Log.w(TAG, "User is locked now.");
+                return false;
+            }
+
+            final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked(
+                    appPackageName, appUserId);
+            final ShortcutInfo current = ps.findShortcutById(shortcutId);
+
+            // The shortcut might have been changed, so we need to do the same validation again.
+            try {
+                if (current == null) {
+                    // It doesn't exist, so it must have all necessary fields.
+                    mService.validateShortcutForPinRequest(request.shortcut);
+                } else {
+                    validateExistingShortcut(current);
+                }
+            } catch (RuntimeException e) {
+                Log.w(TAG, "Unable to pin shortcut: " + e.getMessage());
+                return false;
+            }
+
+            // If the shortcut doesn't exist, need to create it.
+            // First, create it as a dynamic shortcut.
+            if (current == null) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Temporarily adding " + shortcutId + " as dynamic");
+                }
+                // Add as a dynamic shortcut.
+                if (original.getActivity() == null) {
+                    original.setActivity(mService.getDummyMainActivity(appPackageName));
+                }
+                ps.addOrUpdateDynamicShortcut(original);
+            }
+
+            // Pin the shortcut.
+            if (DEBUG) {
+                Slog.d(TAG, "Pinning " + shortcutId);
+            }
+
+            final ShortcutLauncher launcher = mService.getLauncherShortcutsLocked(
+                    launcherPackage, appUserId, launcherUserId);
+            launcher.attemptToRestoreIfNeededAndSave();
+            launcher.addPinnedShortcut(appPackageName, appUserId, shortcutId);
+
+            if (current == null) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Removing " + shortcutId + " as dynamic");
+                }
+                ps.deleteDynamicWithId(shortcutId);
+            }
+
+            ps.adjustRanks(); // Shouldn't be needed, but just in case.
+        }
+
+        mService.verifyStates();
+        mService.packageShortcutsChanged(appPackageName, appUserId);
+
+        return true;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index c5c1c0c..424830b 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -29,6 +29,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.IntentSender.SendIntentException;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -42,8 +44,10 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
 import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
@@ -190,6 +194,8 @@
     private static final String KEY_LOW_RAM = "lowRam";
     private static final String KEY_ICON_SIZE = "iconSize";
 
+    private static final String DUMMY_MAIN_ACTIVITY = "android.__dummy__";
+
     @VisibleForTesting
     interface ConfigConstants {
         /**
@@ -298,6 +304,8 @@
     private final UsageStatsManagerInternal mUsageStatsManagerInternal;
     private final ActivityManagerInternal mActivityManagerInternal;
 
+    private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
+
     @GuardedBy("mLock")
     final SparseIntArray mUidState = new SparseIntArray();
 
@@ -336,8 +344,9 @@
         int IS_ACTIVITY_ENABLED = 13;
         int PACKAGE_UPDATE_CHECK = 14;
         int ASYNC_PRELOAD_USER_DELAY = 15;
+        int GET_DEFAULT_LAUNCHER = 16;
 
-        int COUNT = ASYNC_PRELOAD_USER_DELAY + 1;
+        int COUNT = GET_DEFAULT_LAUNCHER + 1;
     }
 
     private static final String[] STAT_LABELS = {
@@ -356,7 +365,8 @@
             "checkLauncherActivity",
             "isActivityEnabled",
             "packageUpdateCheck",
-            "asyncPreloadUserDelay"
+            "asyncPreloadUserDelay",
+            "getDefaultLauncher()"
     };
 
     final Object mStatLock = new Object();
@@ -417,6 +427,8 @@
         mActivityManagerInternal = Preconditions.checkNotNull(
                 LocalServices.getService(ActivityManagerInternal.class));
 
+        mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
+
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
         }
@@ -1591,12 +1603,11 @@
      * - Make sure the intent's extras are persistable, and them to set
      * {@link ShortcutInfo#mIntentPersistableExtrases}.  Also clear its extras.
      * - Clear flags.
-     *
-     * TODO Detailed unit tests
      */
-    private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate) {
+    private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate,
+            boolean forPinRequest) {
         Preconditions.checkNotNull(shortcut, "Null shortcut detected");
-        if (shortcut.getActivity() != null) {
+        if (!forPinRequest && shortcut.getActivity() != null) {
             Preconditions.checkState(
                     shortcut.getPackage().equals(shortcut.getActivity().getPackageName()),
                     "Cannot publish shortcut: activity " + shortcut.getActivity() + " does not"
@@ -1608,10 +1619,13 @@
         }
 
         if (!forUpdate) {
-            shortcut.enforceMandatoryFields(/* forPinned= */ false);
-            Preconditions.checkArgument(
-                    injectIsMainActivity(shortcut.getActivity(), shortcut.getUserId()),
-                    "Cannot publish shortcut: " + shortcut.getActivity() + " is not main activity");
+            shortcut.enforceMandatoryFields(/* forPinned= */ forPinRequest);
+            if (!forPinRequest) {
+                Preconditions.checkArgument(
+                        injectIsMainActivity(shortcut.getActivity(), shortcut.getUserId()),
+                        "Cannot publish shortcut: " + shortcut.getActivity()
+                                + " is not main activity");
+            }
         }
         if (shortcut.getIcon() != null) {
             ShortcutInfo.validateIcon(shortcut.getIcon());
@@ -1620,11 +1634,18 @@
         shortcut.replaceFlags(0);
     }
 
+    private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate) {
+        fixUpIncomingShortcutInfo(shortcut, forUpdate, /*forPinRequest=*/ false);
+    }
+
+    public void validateShortcutForPinRequest(@NonNull ShortcutInfo shortcut) {
+        fixUpIncomingShortcutInfo(shortcut, /* forUpdate= */ false, /*forPinRequest=*/ true);
+    }
+
     /**
      * When a shortcut has no target activity, set the default one from the package.
      */
     private void fillInDefaultActivity(List<ShortcutInfo> shortcuts) {
-
         ComponentName defaultActivity = null;
         for (int i = shortcuts.size() - 1; i >= 0; i--) {
             final ShortcutInfo si = shortcuts.get(i);
@@ -1834,6 +1855,30 @@
     }
 
     @Override
+    public boolean requestPinShortcut(String packageName, ShortcutInfo shortcut,
+            IntentSender resultIntent, int userId) {
+        verifyCaller(packageName, userId);
+        Preconditions.checkNotNull(shortcut);
+        Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
+
+        final boolean ret;
+        synchronized (mLock) {
+            throwIfUserLockedL(userId);
+
+            // TODO Make sure the caller is in the foreground.
+
+            // TODO Cancel all pending request from the same app.
+
+            // Send request to the launcher, if supported.
+            ret = mShortcutRequestPinProcessor.requestPinShortcutLocked(shortcut, resultIntent);
+        }
+
+        verifyStates();
+
+        return ret;
+    }
+
+    @Override
     public void disableShortcuts(String packageName, List shortcutIds,
             CharSequence disabledMessage, int disabledMessageResId, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
@@ -2049,6 +2094,16 @@
         }
     }
 
+    @Override
+    public boolean isRequestPinShortcutSupported(int callingUserId) {
+        final long token = injectClearCallingIdentity();
+        try {
+            return mShortcutRequestPinProcessor.isRequestPinnedShortcutSupported(callingUserId);
+        } finally {
+            injectRestoreCallingIdentity(token);
+        }
+    }
+
     /**
      * Reset all throttling, for developer options and command line.  Only system/shell can call
      * it.
@@ -2113,77 +2168,22 @@
     // This method is extracted so we can directly call this method from unit tests,
     // even when hasShortcutPermission() is overridden.
     @VisibleForTesting
-    boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
+    boolean hasShortcutHostPermissionInner(@NonNull String packageName, int userId) {
         synchronized (mLock) {
             throwIfUserLockedL(userId);
 
             final ShortcutUser user = getUserShortcutsLocked(userId);
 
-            // Always trust the in-memory cache.
+            // Always trust the cached component.
             final ComponentName cached = user.getCachedLauncher();
             if (cached != null) {
-                if (cached.getPackageName().equals(callingPackage)) {
+                if (cached.getPackageName().equals(packageName)) {
                     return true;
                 }
             }
             // If the cached one doesn't match, then go ahead
 
-            final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
-
-            // Default launcher from package manager.
-            final long startGetHomeActivitiesAsUser = injectElapsedRealtime();
-            final ComponentName defaultLauncher = mPackageManagerInternal
-                    .getHomeActivitiesAsUser(allHomeCandidates, userId);
-            logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeActivitiesAsUser);
-
-            ComponentName detected;
-            if (defaultLauncher != null) {
-                detected = defaultLauncher;
-                if (DEBUG) {
-                    Slog.v(TAG, "Default launcher from PM: " + detected);
-                }
-            } else {
-                detected = user.getLastKnownLauncher();
-
-                if (detected != null) {
-                    if (injectIsActivityEnabledAndExported(detected, userId)) {
-                        if (DEBUG) {
-                            Slog.v(TAG, "Cached launcher: " + detected);
-                        }
-                    } else {
-                        Slog.w(TAG, "Cached launcher " + detected + " no longer exists");
-                        detected = null;
-                        user.clearLauncher();
-                    }
-                }
-            }
-
-            if (detected == null) {
-                // If we reach here, that means it's the first check since the user was created,
-                // and there's already multiple launchers and there's no default set.
-                // Find the system one with the highest priority.
-                // (We need to check the priority too because of FallbackHome in Settings.)
-                // If there's no system launcher yet, then no one can access shortcuts, until
-                // the user explicitly
-                final int size = allHomeCandidates.size();
-
-                int lastPriority = Integer.MIN_VALUE;
-                for (int i = 0; i < size; i++) {
-                    final ResolveInfo ri = allHomeCandidates.get(i);
-                    if (!ri.activityInfo.applicationInfo.isSystemApp()) {
-                        continue;
-                    }
-                    if (DEBUG) {
-                        Slog.d(TAG, String.format("hasShortcutPermissionInner: pkg=%s prio=%d",
-                                ri.activityInfo.getComponentName(), ri.priority));
-                    }
-                    if (ri.priority < lastPriority) {
-                        continue;
-                    }
-                    detected = ri.activityInfo.getComponentName();
-                    lastPriority = ri.priority;
-                }
-            }
+            final ComponentName detected = getDefaultLauncher(userId);
 
             // Update the cache.
             user.setLauncher(detected);
@@ -2191,7 +2191,7 @@
                 if (DEBUG) {
                     Slog.v(TAG, "Detected launcher: " + detected);
                 }
-                return detected.getPackageName().equals(callingPackage);
+                return detected.getPackageName().equals(packageName);
             } else {
                 // Default launcher not found.
                 return false;
@@ -2199,6 +2199,80 @@
         }
     }
 
+    @Nullable
+    ComponentName getDefaultLauncher(@UserIdInt int userId) {
+        final long start = injectElapsedRealtime();
+        final long token = injectClearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                throwIfUserLockedL(userId);
+
+                final ShortcutUser user = getUserShortcutsLocked(userId);
+
+                final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
+
+                // Default launcher from package manager.
+                final long startGetHomeActivitiesAsUser = injectElapsedRealtime();
+                final ComponentName defaultLauncher = mPackageManagerInternal
+                        .getHomeActivitiesAsUser(allHomeCandidates, userId);
+                logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeActivitiesAsUser);
+
+                ComponentName detected = null;
+                if (defaultLauncher != null) {
+                    detected = defaultLauncher;
+                    if (DEBUG) {
+                        Slog.v(TAG, "Default launcher from PM: " + detected);
+                    }
+                } else {
+                    detected = user.getLastKnownLauncher();
+
+                    if (detected != null) {
+                        if (injectIsActivityEnabledAndExported(detected, userId)) {
+                            if (DEBUG) {
+                                Slog.v(TAG, "Cached launcher: " + detected);
+                            }
+                        } else {
+                            Slog.w(TAG, "Cached launcher " + detected + " no longer exists");
+                            detected = null;
+                            user.clearLauncher();
+                        }
+                    }
+                }
+
+                if (detected == null) {
+                    // If we reach here, that means it's the first check since the user was created,
+                    // and there's already multiple launchers and there's no default set.
+                    // Find the system one with the highest priority.
+                    // (We need to check the priority too because of FallbackHome in Settings.)
+                    // If there's no system launcher yet, then no one can access shortcuts, until
+                    // the user explicitly
+                    final int size = allHomeCandidates.size();
+
+                    int lastPriority = Integer.MIN_VALUE;
+                    for (int i = 0; i < size; i++) {
+                        final ResolveInfo ri = allHomeCandidates.get(i);
+                        if (!ri.activityInfo.applicationInfo.isSystemApp()) {
+                            continue;
+                        }
+                        if (DEBUG) {
+                            Slog.d(TAG, String.format("hasShortcutPermissionInner: pkg=%s prio=%d",
+                                    ri.activityInfo.getComponentName(), ri.priority));
+                        }
+                        if (ri.priority < lastPriority) {
+                            continue;
+                        }
+                        detected = ri.activityInfo.getComponentName();
+                        lastPriority = ri.priority;
+                    }
+                }
+                return detected;
+            }
+        } finally {
+            injectRestoreCallingIdentity(token);
+            logDurationStat(Stats.GET_DEFAULT_LAUNCHER, start);
+        }
+    }
+
     // === House keeping ===
 
     private void cleanUpPackageForAllLoadedUsers(String packageName, @UserIdInt int packageUserId,
@@ -3034,10 +3108,21 @@
         if (activity != null) {
             baseIntent.setComponent(activity);
         }
+        return queryActivities(baseIntent, userId, /* exportedOnly =*/ true);
+    }
 
-        final List<ResolveInfo> resolved =
-                mContext.getPackageManager().queryIntentActivitiesAsUser(
-                        baseIntent, PACKAGE_MATCH_FLAGS, userId);
+    @NonNull
+    List<ResolveInfo> queryActivities(@NonNull Intent intent, int userId,
+            boolean exportedOnly) {
+        final List<ResolveInfo> resolved;
+        final long token = injectClearCallingIdentity();
+        try {
+            resolved =
+                    mContext.getPackageManager().queryIntentActivitiesAsUser(
+                            intent, PACKAGE_MATCH_FLAGS, userId);
+        } finally {
+            injectRestoreCallingIdentity(token);
+        }
         if (resolved == null || resolved.size() == 0) {
             return EMPTY_RESOLVE_INFO;
         }
@@ -3045,7 +3130,9 @@
         if (!isInstalled(resolved.get(0).activityInfo)) {
             return EMPTY_RESOLVE_INFO;
         }
-        resolved.removeIf(ACTIVITY_NOT_EXPORTED);
+        if (exportedOnly) {
+            resolved.removeIf(ACTIVITY_NOT_EXPORTED);
+        }
         return resolved;
     }
 
@@ -3056,14 +3143,11 @@
     @Nullable
     ComponentName injectGetDefaultMainActivity(@NonNull String packageName, int userId) {
         final long start = injectElapsedRealtime();
-        final long token = injectClearCallingIdentity();
         try {
             final List<ResolveInfo> resolved =
                     queryActivities(getMainActivityIntent(), packageName, null, userId);
             return resolved.size() == 0 ? null : resolved.get(0).activityInfo.getComponentName();
         } finally {
-            injectRestoreCallingIdentity(token);
-
             logDurationStat(Stats.GET_LAUNCHER_ACTIVITY, start);
         }
     }
@@ -3073,31 +3157,36 @@
      */
     boolean injectIsMainActivity(@NonNull ComponentName activity, int userId) {
         final long start = injectElapsedRealtime();
-        final long token = injectClearCallingIdentity();
         try {
-            final List<ResolveInfo> resolved =
-                    queryActivities(getMainActivityIntent(), activity.getPackageName(),
-                            activity, userId);
+            if (DUMMY_MAIN_ACTIVITY.equals(activity.getClassName())) {
+                return true;
+            }
+            final List<ResolveInfo> resolved = queryActivities(
+                    getMainActivityIntent(), activity.getPackageName(), activity, userId);
             return resolved.size() > 0;
         } finally {
-            injectRestoreCallingIdentity(token);
-
             logDurationStat(Stats.CHECK_LAUNCHER_ACTIVITY, start);
         }
     }
 
     /**
+     * Create a dummy "main activity" component name which is used to create a dynamic shortcut
+     * with no main activity temporarily.
+     */
+    @NonNull
+    ComponentName getDummyMainActivity(@NonNull String packageName) {
+        return new ComponentName(packageName, DUMMY_MAIN_ACTIVITY);
+    }
+
+    /**
      * Return all the enabled, exported and main activities from a package.
      */
     @NonNull
     List<ResolveInfo> injectGetMainActivities(@NonNull String packageName, int userId) {
         final long start = injectElapsedRealtime();
-        final long token = injectClearCallingIdentity();
         try {
             return queryActivities(getMainActivityIntent(), packageName, null, userId);
         } finally {
-            injectRestoreCallingIdentity(token);
-
             logDurationStat(Stats.CHECK_LAUNCHER_ACTIVITY, start);
         }
     }
@@ -3109,17 +3198,33 @@
     boolean injectIsActivityEnabledAndExported(
             @NonNull ComponentName activity, @UserIdInt int userId) {
         final long start = injectElapsedRealtime();
-        final long token = injectClearCallingIdentity();
         try {
             return queryActivities(new Intent(), activity.getPackageName(), activity, userId)
                     .size() > 0;
         } finally {
-            injectRestoreCallingIdentity(token);
-
             logDurationStat(Stats.IS_ACTIVITY_ENABLED, start);
         }
     }
 
+    /**
+     * Get the {@link LauncherApps#ACTION_CONFIRM_PIN_ITEM} activity in a given package.
+     */
+    @Nullable
+    ComponentName injectGetPinConfirmationActivity(@NonNull String launcherPackageName,
+            int launcherUserId) {
+        Preconditions.checkNotNull(launcherPackageName);
+
+        final Intent confirmIntent = new Intent(LauncherApps.ACTION_CONFIRM_PIN_ITEM);
+        confirmIntent.setPackage(launcherPackageName);
+
+        final List<ResolveInfo> candidates = queryActivities(
+                confirmIntent, launcherUserId, /* exportedOnly =*/ false);
+        for (ResolveInfo ri : candidates) {
+            return ri.activityInfo.getComponentName();
+        }
+        return null;
+    }
+
     boolean injectIsSafeModeEnabled() {
         final long token = injectClearCallingIdentity();
         try {
@@ -3133,6 +3238,32 @@
         }
     }
 
+    /**
+     * If {@code userId} is of a managed profile, return the parent user ID.  Otherwise return
+     * itself.
+     */
+    int getParentOrSelfUserId(int userId) {
+        final long token = injectClearCallingIdentity();
+        try {
+            final UserInfo parent = mUserManager.getProfileParent(userId);
+            return (parent != null) ? parent.id : userId;
+        } finally {
+            injectRestoreCallingIdentity(token);
+        }
+    }
+
+    void injectSendIntentSender(IntentSender intentSender) {
+        if (intentSender == null) {
+            return;
+        }
+        try {
+            intentSender.sendIntent(mContext, /* code= */ 0, /* intent= */ null,
+                    /* onFinished=*/ null, /* handler= */ null);
+        } catch (SendIntentException e) {
+            Slog.w(TAG, "sendIntent failed().", e);
+        }
+    }
+
     // === Backup & restore ===
 
     boolean shouldBackupApp(String packageName, int userId) {
@@ -3749,6 +3880,11 @@
         }
     }
 
+    @VisibleForTesting
+    ShortcutRequestPinProcessor getShortcutRequestPinProcessorForTest() {
+        return mShortcutRequestPinProcessor;
+    }
+
     /**
      * Control whether {@link #verifyStates} should be performed.  We always perform it during unit
      * tests.
