Adding support for new APIs in O related to configurable shortcuts

> Config activities can now return PinItemRequest which can be used to pin
  deep shortcuts

Bug: 33584624
Change-Id: Ic0df436bd79e069615b9d60d24eb7594b824b2da
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 6535d65..5b487b6 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -189,6 +189,10 @@
         return getFullResDefaultActivityIcon();
     }
 
+    public Drawable getFullResIcon(LauncherActivityInfo info) {
+        return mIconProvider.getIcon(info, mIconDpi);
+    }
+
     protected Bitmap makeDefaultIcon(UserHandle user) {
         Drawable unbadged = getFullResDefaultActivityIcon();
         return LauncherIcons.createBadgedIconBitmap(unbadged, user, mContext);
@@ -376,8 +380,7 @@
         }
         if (entry == null) {
             entry = new CacheEntry();
-            entry.icon = LauncherIcons.createBadgedIconBitmap(
-                    mIconProvider.getIcon(app, mIconDpi), app.getUser(),
+            entry.icon = LauncherIcons.createBadgedIconBitmap(getFullResIcon(app), app.getUser(),
                     mContext);
         }
         entry.title = app.getLabel();
@@ -535,8 +538,7 @@
 
                 if (info != null) {
                     entry.icon = LauncherIcons.createBadgedIconBitmap(
-                            mIconProvider.getIcon(info, mIconDpi), info.getUser(),
-                            mContext);
+                            getFullResIcon(info), info.getUser(), mContext);
                 } else {
                     if (usePackageIcon) {
                         CacheEntry packageEntry = getEntryForPackageLocked(
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 13534b9..9245f18 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -86,6 +86,7 @@
 import com.android.launcher3.anim.AnimationLayerSet;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PinItemRequestCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.config.ProviderConfig;
@@ -96,6 +97,7 @@
 import com.android.launcher3.dynamicui.ExtractedColors;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.keyboard.CustomActionsPopup;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.logging.FileLog;
@@ -105,6 +107,7 @@
 import com.android.launcher3.pageindicators.PageIndicator;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.DeepShortcutsContainer;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -118,6 +121,7 @@
 import com.android.launcher3.util.TestingUtils;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 import com.android.launcher3.widget.WidgetsContainerView;
@@ -1430,19 +1434,42 @@
         int[] cellXY = mTmpAddItemCellCoordinates;
         CellLayout layout = getCellLayout(container, screenId);
 
-        ShortcutInfo info = InstallShortcutReceiver.fromShortcutIntent(this, data);
-        if (info == null || args.getRequestCode() != REQUEST_CREATE_SHORTCUT ||
+        if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT ||
                 args.getPendingIntent().getComponent() == null) {
             return;
         }
-        if (!PackageManagerHelper.hasPermissionForActivity(
-                this, info.intent, args.getPendingIntent().getComponent().getPackageName())) {
-            // The app is trying to add a shortcut without sufficient permissions
-            Log.e(TAG, "Ignoring malicious intent " + info.intent.toUri(0));
-            return;
-        }
-        final View view = createShortcut(info);
 
+        ShortcutInfo info = null;
+        if (Utilities.isAtLeastO()) {
+            PinItemRequestCompat request = PinItemRequestCompat.getPinItemRequest(data);
+            // request.accept will initiate a shortcutChanged callback. To ensure that the model is
+            // consistent, that callback must be processed by the model, after the ShortcutInfo is
+            // added to the model. This is guaranteed here the callback comes on the UI thread, and
+            // we will add the shortcut on the UI thread as well.
+            if (request != null &&
+                    request.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT &&
+                    request.isValid() && request.accept()) {
+                ShortcutInfoCompat compat = new ShortcutInfoCompat(request.getShortcutInfo());
+                info = new ShortcutInfo(compat, this);
+                // Apply the unbadged icon and fetch the actual icon asynchronously.
+                info.iconBitmap = LauncherIcons
+                        .createShortcutIcon(compat, this, false /* badged */);
+                getModel().updateAndBindShortcutInfo(info, compat);
+            }
+        }
+
+        if (info == null) {
+            info = InstallShortcutReceiver.fromShortcutIntent(this, data);
+
+            if (info == null || !PackageManagerHelper.hasPermissionForActivity(
+                    this, info.intent, args.getPendingIntent().getComponent().getPackageName())) {
+                // The app is trying to add a shortcut without sufficient permissions
+                Log.e(TAG, "Ignoring malicious intent " + info.intent.toUri(0));
+                return;
+            }
+        }
+
+        final View view = createShortcut(info);
         boolean foundCellSpan = false;
         // First we check if we already know the exact location where we want to add this item.
         if (cellX >= 0 && cellY >= 0) {
@@ -2025,7 +2052,7 @@
                 addAppWidgetFromDrop((PendingAddWidgetInfo) info);
                 break;
             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
-                processShortcutFromDrop(info);
+                processShortcutFromDrop((PendingAddShortcutInfo) info);
                 break;
             default:
                 throw new IllegalStateException("Unknown item type: " + info.itemType);
@@ -2035,10 +2062,12 @@
     /**
      * Process a shortcut drop.
      */
-    private void processShortcutFromDrop(PendingAddItemInfo info) {
+    private void processShortcutFromDrop(PendingAddShortcutInfo info) {
         Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(info.componentName);
         setWaitingForResult(PendingRequestArgs.forIntent(REQUEST_CREATE_SHORTCUT, intent, info));
-        Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);
+        if (!info.activityInfo.startConfigActivity(this, REQUEST_CREATE_SHORTCUT)) {
+            handleActivityResult(REQUEST_CREATE_SHORTCUT, RESULT_CANCELED, null);
+        }
     }
 
     /**
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 8ad0144..267cb2a 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,9 +16,7 @@
 
 package com.android.launcher3;
 
-import android.app.Activity;
 import android.app.WallpaperManager;
-import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -53,7 +51,6 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.Toast;
 
 import com.android.launcher3.config.ProviderConfig;
 
@@ -262,20 +259,6 @@
         return scale;
     }
 
-    public static void startActivityForResultSafely(
-            Activity activity, Intent intent, int requestCode) {
-        try {
-            activity.startActivityForResult(intent, requestCode);
-        } catch (ActivityNotFoundException e) {
-            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-        } catch (SecurityException e) {
-            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
-                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
-                    "or use the exported attribute for this activity.", e);
-        }
-    }
-
     static boolean isSystemApp(Context context, Intent intent) {
         PackageManager pm = context.getPackageManager();
         ComponentName cn = intent.getComponent();
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 83c978e..33d6362 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -3,7 +3,6 @@
 import android.content.ComponentName;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -30,6 +29,7 @@
 import android.util.LongSparseArray;
 
 import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.util.ComponentKey;
@@ -414,8 +414,8 @@
         return mWidgetManager.getBadgeBitmap(info, preview, imageWidth, imageHeight);
     }
 
-    private Bitmap generateShortcutPreview(
-            BaseActivity launcher, ActivityInfo info, int maxWidth, int maxHeight, Bitmap preview) {
+    private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
+            int maxWidth, int maxHeight, Bitmap preview) {
         final Canvas c = new Canvas();
         if (preview == null) {
             preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888);
@@ -428,7 +428,7 @@
             c.drawColor(0, PorterDuff.Mode.CLEAR);
         }
 
-        Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info));
+        Drawable icon = mutateOnMainThread(info.getFullResIcon(mIconCache));
         icon.setFilterBitmap(true);
 
         // Draw a desaturated/scaled version of the icon in the background as a watermark
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 5c6eef8..281069a 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 
+import com.android.launcher3.Utilities;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 
 import java.util.List;
@@ -51,7 +52,11 @@
     public static LauncherAppsCompat getInstance(Context context) {
         synchronized (sInstanceLock) {
             if (sInstance == null) {
-                sInstance = new LauncherAppsCompatVL(context.getApplicationContext());
+                if (Utilities.isAtLeastO()) {
+                    sInstance = new LauncherAppsCompatVO(context.getApplicationContext());
+                } else {
+                    sInstance = new LauncherAppsCompatVL(context.getApplicationContext());
+                }
             }
             return sInstance;
         }
@@ -69,4 +74,5 @@
     public abstract boolean isPackageEnabledForProfile(String packageName, UserHandle user);
     public abstract boolean isActivityEnabledForProfile(ComponentName component,
             UserHandle user);
+    public abstract List<ShortcutConfigActivityInfo> getCustomShortcutActivityList();
 }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index e2739c1..3cb721c 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -21,11 +21,14 @@
 import android.content.Intent;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.UserHandle;
 
+import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 
 import java.util.ArrayList;
@@ -35,11 +38,13 @@
 
 public class LauncherAppsCompatVL extends LauncherAppsCompat {
 
-    protected LauncherApps mLauncherApps;
+    protected final LauncherApps mLauncherApps;
+    protected final Context mContext;
 
     private Map<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks = new HashMap<>();
 
     LauncherAppsCompatVL(Context context) {
+        mContext = context;
         mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
     }
 
@@ -140,5 +145,16 @@
             mCallback.onShortcutsChanged(packageName, shortcutInfoCompats, user);
         }
     }
+
+    @Override
+    public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList() {
+        PackageManager pm = mContext.getPackageManager();
+        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
+        for (ResolveInfo info :
+                pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
+            result.add(new ShortcutConfigActivityInfoVL(info.activityInfo, pm));
+        }
+        return result;
+    }
 }
 
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
new file mode 100644
index 0000000..0610726
--- /dev/null
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.launcher3.compat;
+
+import android.content.Context;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo.*;
+
+public class LauncherAppsCompatVO extends LauncherAppsCompatVL {
+
+    LauncherAppsCompatVO(Context context) {
+        super(context);
+    }
+
+    @Override
+    public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList() {
+        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
+
+        try {
+            Method m = LauncherApps.class.getDeclaredMethod("getShortcutConfigActivityList",
+                    String.class, UserHandle.class);
+            for (UserHandle user : UserManagerCompat.getInstance(mContext).getUserProfiles()) {
+                List<LauncherActivityInfo> activities =
+                        (List<LauncherActivityInfo>) m.invoke(mLauncherApps, null, user);
+                for (LauncherActivityInfo activityInfo : activities) {
+                    result.add(new ShortcutConfigActivityInfoVO(activityInfo));
+                }
+            }
+        } catch (Exception e) {
+            Log.e("LauncherAppsCompatVO", "Error calling new API", e);
+        }
+
+        return result;
+    }
+}
diff --git a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
new file mode 100644
index 0000000..dd375df
--- /dev/null
+++ b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 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.launcher3.compat;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+import java.lang.reflect.Method;
+
+/**
+ * Wrapper class for representing a shortcut configure activity.
+ */
+public abstract class ShortcutConfigActivityInfo {
+
+    private static final String TAG = "SCActivityInfo";
+
+    private final ComponentName mCn;
+    private final UserHandle mUser;
+
+    private ShortcutConfigActivityInfo(ComponentName cn, UserHandle user) {
+        mCn = cn;
+        mUser = user;
+    }
+
+    public ComponentName getComponent() {
+        return mCn;
+    }
+
+    public UserHandle getUser() {
+        return mUser;
+    }
+
+    public abstract CharSequence getLabel();
+
+    public abstract Drawable getFullResIcon(IconCache cache);
+
+    public boolean startConfigActivity(Activity activity, int requestCode) {
+        Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT)
+                .setComponent(getComponent());
+        try {
+            activity.startActivityForResult(intent, requestCode);
+            return true;
+        } catch (ActivityNotFoundException e) {
+            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+        } catch (SecurityException e) {
+            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+            Log.e(TAG, "Launcher does not have the permission to launch " + intent +
+                    ". Make sure to create a MAIN intent-filter for the corresponding activity " +
+                    "or use the exported attribute for this activity.", e);
+        }
+        return false;
+    }
+
+    static class ShortcutConfigActivityInfoVL extends ShortcutConfigActivityInfo {
+
+        private final ActivityInfo mInfo;
+        private final PackageManager mPm;
+
+
+        public ShortcutConfigActivityInfoVL(ActivityInfo info, PackageManager pm) {
+            super(new ComponentName(info.packageName, info.name), Process.myUserHandle());
+            mInfo = info;
+            mPm = pm;
+        }
+
+        @Override
+        public CharSequence getLabel() {
+            return mInfo.loadLabel(mPm);
+        }
+
+        @Override
+        public Drawable getFullResIcon(IconCache cache) {
+            return cache.getFullResIcon(mInfo);
+        }
+    }
+
+    @TargetApi(26)
+    static class ShortcutConfigActivityInfoVO extends ShortcutConfigActivityInfo {
+
+        private final LauncherActivityInfo mInfo;
+
+        public ShortcutConfigActivityInfoVO(LauncherActivityInfo info) {
+            super(info.getComponentName(), info.getUser());
+            mInfo = info;
+        }
+
+        @Override
+        public CharSequence getLabel() {
+            return mInfo.getLabel();
+        }
+
+        @Override
+        public Drawable getFullResIcon(IconCache cache) {
+            return cache.getFullResIcon(mInfo);
+        }
+
+        @Override
+        public boolean startConfigActivity(Activity activity, int requestCode) {
+            if (getUser().equals(Process.myUserHandle())) {
+                return super.startConfigActivity(activity, requestCode);
+            }
+            try {
+                Method m = LauncherApps.class.getDeclaredMethod(
+                        "getShortcutConfigActivityIntent", LauncherActivityInfo.class);
+                IntentSender is = (IntentSender) m.invoke(
+                        activity.getSystemService(LauncherApps.class), mInfo);
+                activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0);
+                return true;
+            } catch (Exception e) {
+                Log.e(TAG, "Error calling new API", e);
+                return false;
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher3/model/WidgetItem.java b/src/com/android/launcher3/model/WidgetItem.java
index c256176..1e96dec 100644
--- a/src/com/android/launcher3/model/WidgetItem.java
+++ b/src/com/android/launcher3/model/WidgetItem.java
@@ -1,16 +1,14 @@
 package com.android.launcher3.model;
 
-import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.os.Process;
 import android.os.UserHandle;
 
 import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.util.ComponentKey;
 
 import java.text.Collator;
@@ -26,7 +24,7 @@
     private static Collator sCollator;
 
     public final LauncherAppWidgetProviderInfo widgetInfo;
-    public final ActivityInfo activityInfo;
+    public final ShortcutConfigActivityInfo activityInfo;
 
     public final String label;
     public final int spanX, spanY;
@@ -43,12 +41,11 @@
         spanY = Math.min(info.spanY, idp.numRows);
     }
 
-    public WidgetItem(ResolveInfo info, PackageManager pm) {
-        super(new ComponentName(info.activityInfo.packageName, info.activityInfo.name),
-                Process.myUserHandle());
-        label = Utilities.trim(info.loadLabel(pm));
+    public WidgetItem(ShortcutConfigActivityInfo info) {
+        super(info.getComponent(), info.getUser());
+        label = Utilities.trim(info.getLabel());
         widgetInfo = null;
-        activityInfo = info.activityInfo;
+        activityInfo = info;
         spanX = spanY = 1;
     }
 
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index 2c62f89..95c54f7 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -17,6 +17,9 @@
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo;
+import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.Preconditions;
@@ -70,9 +73,9 @@
             }
 
             // Shortcuts
-            for (ResolveInfo info :
-                    pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
-                widgetsAndShortcuts.add(new WidgetItem(info, pm));
+            for (ShortcutConfigActivityInfo info : LauncherAppsCompat.getInstance(context)
+                    .getCustomShortcutActivityList()) {
+                widgetsAndShortcuts.add(new WidgetItem(info));
             }
             setWidgetsAndShortcuts(widgetsAndShortcuts, context);
         } catch (Exception e) {
diff --git a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
index 486b18e..7eeb8bf 100644
--- a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
@@ -15,11 +15,9 @@
  */
 package com.android.launcher3.widget;
 
-import android.content.ComponentName;
-import android.content.pm.ActivityInfo;
-
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.PendingAddItemInfo;
+import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 
 /**
  * Meta data used for late binding of the short cuts.
@@ -28,11 +26,12 @@
  */
 public class PendingAddShortcutInfo extends PendingAddItemInfo {
 
-    ActivityInfo activityInfo;
+    public ShortcutConfigActivityInfo activityInfo;
 
-    public PendingAddShortcutInfo(ActivityInfo activityInfo) {
+    public PendingAddShortcutInfo(ShortcutConfigActivityInfo activityInfo) {
         this.activityInfo = activityInfo;
-        componentName = new ComponentName(activityInfo.packageName, activityInfo.name);
+        componentName = activityInfo.getComponent();
+        user = activityInfo.getUser();
         itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
     }
 }
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index be4f635..2731fb9 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -224,7 +224,7 @@
             scale = bounds.width() / (float) preview.getWidth();
         } else {
             PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
-            Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.activityInfo);
+            Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(mIconCache);
             preview = LauncherIcons.createIconBitmap(icon, mLauncher);
             createItemInfo.spanX = createItemInfo.spanY = 1;
             scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / preview.getWidth();