Merge "Removing static instance of LauncherAppsCompat and unnecessary wrapper classes" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 2e59ed5..e86a1c1 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -25,6 +25,7 @@
 import android.app.ActivityManager;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
+import android.content.pm.LauncherApps;
 import android.os.Build;
 import android.os.Looper;
 import android.os.Process;
@@ -32,8 +33,6 @@
 import android.os.UserHandle;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
@@ -211,18 +210,28 @@
     }
 
     private void setupPackageListener() {
-        LauncherAppsCompat.getInstance(mContext)
-                .addOnAppsChangedCallback(new OnAppsChangedCallbackCompat() {
-                    @Override
-                    public void onPackageRemoved(String packageName, UserHandle user) {
-                        mIconCache.invalidatePackage(packageName);
-                    }
+        mContext.getSystemService(LauncherApps.class).registerCallback(new LauncherApps.Callback() {
+            @Override
+            public void onPackageRemoved(String packageName, UserHandle user) {
+                mIconCache.invalidatePackage(packageName);
+            }
 
-                    @Override
-                    public void onPackageChanged(String packageName, UserHandle user) {
-                        mIconCache.invalidatePackage(packageName);
-                    }
-                });
+            @Override
+            public void onPackageChanged(String packageName, UserHandle user) {
+                mIconCache.invalidatePackage(packageName);
+            }
+
+            @Override
+            public void onPackageAdded(String packageName, UserHandle user) { }
+
+            @Override
+            public void onPackagesAvailable(
+                    String[] packageNames, UserHandle user, boolean replacing) { }
+
+            @Override
+            public void onPackagesUnavailable(
+                    String[] packageNames, UserHandle user, boolean replacing) { }
+        });
     }
 
     public void addThumbnailChangeListener(TaskThumbnailChangeListener listener) {
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index 5f76ca7..230a22a 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -23,9 +23,9 @@
 import android.os.UserHandle;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageManagerHelper;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
@@ -44,15 +44,14 @@
      * TODO: remove this once we switch to getting the icon and label from IconCache.
      */
     public static CharSequence getTitle(Context context, Task task) {
-        LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context);
-        PackageManager packageManager = context.getPackageManager();
         UserHandle user = UserHandle.of(task.key.userId);
-        ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo(
-            task.getTopComponent().getPackageName(), 0, user);
+        ApplicationInfo applicationInfo = new PackageManagerHelper(context)
+                .getApplicationInfo(task.getTopComponent().getPackageName(), user, 0);
         if (applicationInfo == null) {
             Log.e(TAG, "Failed to get title for task " + task);
             return "";
         }
+        PackageManager packageManager = context.getPackageManager();
         return packageManager.getUserBadgedLabel(
             applicationInfo.loadLabel(packageManager), user);
     }
diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
index 7801775..8e4762d 100644
--- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
+++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
@@ -24,6 +24,7 @@
 import android.app.prediction.AppTargetId;
 import android.content.ComponentName;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.os.Process;
 import android.view.View;
 
@@ -35,7 +36,6 @@
 import com.android.launcher3.appprediction.PredictionRowView;
 import com.android.launcher3.appprediction.PredictionUiStateManager;
 import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.model.AppLaunchTracker;
 
 import org.junit.After;
@@ -60,7 +60,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mTargetContext)
+        List<LauncherActivityInfo> activities = mTargetContext.getSystemService(LauncherApps.class)
                 .getActivityList(null, Process.myUserHandle());
         mSampleApp1 = activities.get(0);
         mSampleApp2 = activities.get(1);
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index e2ef337..00a06ae 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -19,6 +19,7 @@
 import android.app.ActivityOptions;
 import android.content.ActivityNotFoundException;
 import android.content.Intent;
+import android.content.pm.LauncherApps;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -33,7 +34,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.model.AppLaunchTracker;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.uioverrides.DejankBinderTracker;
@@ -168,7 +168,7 @@
                 AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
                         Process.myUserHandle(), sourceContainer);
             } else {
-                LauncherAppsCompat.getInstance(this).startActivityForProfile(
+                getSystemService(LauncherApps.class).startMainActivity(
                         intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
                 AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), user,
                         sourceContainer);
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index c9eca9d..8ebf464 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -26,6 +26,7 @@
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.graphics.Bitmap;
@@ -40,7 +41,6 @@
 
 import androidx.annotation.WorkerThread;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.GraphicsUtils;
@@ -122,7 +122,7 @@
             return;
         }
 
-        LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+        LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
         for (String encoded : strings) {
             PendingInstallShortcutInfo info = decode(encoded, context);
             if (info == null) {
@@ -131,7 +131,7 @@
 
             String pkg = getIntentPackage(info.launchIntent);
             if (!TextUtils.isEmpty(pkg)
-                    && !launcherApps.isPackageEnabledForProfile(pkg, info.user)
+                    && !launcherApps.isPackageEnabled(pkg, info.user)
                     && !info.isActivity) {
                 if (DBG) {
                     Log.d(TAG, "Ignoring shortcut for absent package: " + info.launchIntent);
@@ -519,7 +519,7 @@
         try {
             Decoder decoder = new Decoder(encoded, context);
             if (decoder.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
-                LauncherActivityInfo info = LauncherAppsCompat.getInstance(context)
+                LauncherActivityInfo info = context.getSystemService(LauncherApps.class)
                         .resolveActivity(decoder.launcherIntent, decoder.user);
                 if (info != null) {
                     return new PendingInstallShortcutInfo(info, context);
@@ -609,7 +609,7 @@
             return original;
         }
 
-        LauncherActivityInfo info = LauncherAppsCompat.getInstance(original.mContext)
+        LauncherActivityInfo info = original.mContext.getSystemService(LauncherApps.class)
                 .resolveActivity(original.launchIntent, original.user);
         if (info == null) {
             return original;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index aff4c90..c92d917 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -90,7 +90,6 @@
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DragController;
@@ -110,6 +109,7 @@
 import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.notification.NotificationListener;
+import com.android.launcher3.pm.PinRequestHelper;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.qsb.QsbContainerView;
@@ -1230,8 +1230,8 @@
 
         WorkspaceItemInfo info = null;
         if (Utilities.ATLEAST_OREO) {
-            info = LauncherAppsCompatVO.createWorkspaceItemFromPinItemRequest(
-                    this, LauncherAppsCompatVO.getPinItemRequest(data), 0);
+            info = PinRequestHelper.createWorkspaceItemFromPinItemRequest(
+                    this, PinRequestHelper.getPinItemRequest(data), 0);
         }
 
         if (info == null) {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 018b48f..c717d1a 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -23,11 +23,10 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
+import android.content.pm.LauncherApps;
 import android.os.Handler;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.IconCache;
@@ -38,6 +37,7 @@
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.SecureSettingsObserver;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.launcher3.widget.custom.CustomWidgetManager;
 
 public class LauncherAppState {
@@ -56,6 +56,7 @@
     private final SecureSettingsObserver mNotificationDotsObserver;
 
     private final InstallSessionTracker mInstallSessionTracker;
+    private final SimpleBroadcastReceiver mModelChangeReceiver;
 
     public static LauncherAppState getInstance(final Context context) {
         return INSTANCE.get(context);
@@ -79,27 +80,23 @@
         mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
         mModel = new LauncherModel(this, mIconCache, AppFilter.newInstance(mContext));
 
-        LauncherAppsCompat.getInstance(mContext).addOnAppsChangedCallback(mModel);
+        mModelChangeReceiver = new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
 
-        // Register intent receivers
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
-        // For handling managed profiles
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
-
+        mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
+        mModelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
+                Intent.ACTION_MANAGED_PROFILE_ADDED,
+                Intent.ACTION_MANAGED_PROFILE_REMOVED,
+                Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
+                Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
+                Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
         if (FeatureFlags.IS_DOGFOOD_BUILD) {
-            filter.addAction(ACTION_FORCE_ROLOAD);
+            mModelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
         }
         // TODO: remove listener on terminate
         FeatureFlags.APP_SEARCH_IMPROVEMENTS.addChangeListener(context, mModel::forceReload);
         CustomWidgetManager.INSTANCE.get(mContext)
                 .setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
 
-        mContext.registerReceiver(mModel, filter);
         UserManagerCompat.getInstance(mContext).enableAndResetCache();
         mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
         new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
@@ -143,9 +140,8 @@
      * Call from Application.onTerminate(), which is not guaranteed to ever be called.
      */
     public void onTerminate() {
-        mContext.unregisterReceiver(mModel);
-        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
-        launcherApps.removeOnAppsChangedCallback(mModel);
+        mContext.unregisterReceiver(mModelChangeReceiver);
+        mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
         mInstallSessionTracker.unregister();
         CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
 
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index f360325..bea25e0 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -21,9 +21,8 @@
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
-import android.content.BroadcastReceiver;
-import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller;
 import android.content.pm.ShortcutInfo;
 import android.os.UserHandle;
@@ -33,7 +32,6 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.IconCache;
@@ -76,8 +74,7 @@
  * LauncherModel object held in a static. Also provide APIs for updating the database state
  * for the Launcher.
  */
-public class LauncherModel extends BroadcastReceiver
-        implements LauncherAppsCompat.OnAppsChangedCallbackCompat, InstallSessionTracker.Callback {
+public class LauncherModel extends LauncherApps.Callback implements InstallSessionTracker.Callback {
     private static final boolean DEBUG_RECEIVER = false;
 
     static final String TAG = "Launcher.Model";
@@ -217,12 +214,7 @@
         enqueueModelUpdateTask(new ShortcutsChangedTask(packageName, shortcuts, user, false));
     }
 
-    /**
-     * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and
-     * ACTION_PACKAGE_CHANGED.
-     */
-    @Override
-    public void onReceive(Context context, Intent intent) {
+    public void onBroadcastIntent(Intent intent) {
         if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent);
         final String action = intent.getAction();
         if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
@@ -230,7 +222,7 @@
             forceReload();
         } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)
                 || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
-            UserManagerCompat.getInstance(context).enableAndResetCache();
+            UserManagerCompat.getInstance(mApp.getContext()).enableAndResetCache();
             forceReload();
         } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
                 Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index c8c590d..3c2ed72 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -16,6 +16,7 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Bundle;
@@ -28,12 +29,12 @@
 import android.widget.Toast;
 
 import com.android.launcher3.Launcher.OnResumeCallback;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.logging.LoggerUtils;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.Themes;
 
 import java.net.URISyntaxException;
@@ -157,7 +158,7 @@
             user = item.user;
         }
         if (intent != null) {
-            LauncherActivityInfo info = LauncherAppsCompat.getInstance(mLauncher)
+            LauncherActivityInfo info = mLauncher.getSystemService(LauncherApps.class)
                     .resolveActivity(intent, user);
             if (info != null
                     && (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -287,9 +288,8 @@
         @Override
         public void onLauncherResume() {
             // We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well.
-            if (LauncherAppsCompat.getInstance(mContext)
-                    .getApplicationInfo(mPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
-                            mDragObject.dragInfo.user) == null) {
+            if (new PackageManagerHelper(mContext).getApplicationInfo(mPackageName,
+                    mDragObject.dragInfo.user, PackageManager.MATCH_UNINSTALLED_PACKAGES) == null) {
                 mDragObject.dragSource = mOriginal;
                 mOriginal.onDropCompleted(SecondaryDropTarget.this, mDragObject, true);
             } else {
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 55402dd..8dedc6c 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageManager;
@@ -39,7 +40,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.pm.PackageInstallerCompat;
 import com.android.launcher3.util.Executors;
 
@@ -85,9 +85,8 @@
 
     public static void queuePromiseAppIconAddition(Context context, SessionInfo sessionInfo) {
         String packageName = sessionInfo.getAppPackageName();
-        List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
-                .getActivityList(packageName, getUserHandle(sessionInfo));
-        if (activities == null || activities.isEmpty()) {
+        if (context.getSystemService(LauncherApps.class)
+                .getActivityList(packageName, getUserHandle(sessionInfo)).isEmpty()) {
             // Ensure application isn't already installed.
             queueAppIconAddition(context, packageName, sessionInfo.getAppLabel(),
                     sessionInfo.getAppIcon(), getUserHandle(sessionInfo));
@@ -95,9 +94,9 @@
     }
 
     public static void queueAppIconAddition(Context context, String packageName, UserHandle user) {
-        List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
+        List<LauncherActivityInfo> activities = context.getSystemService(LauncherApps.class)
                 .getActivityList(packageName, user);
-        if (activities == null || activities.isEmpty()) {
+        if (activities.isEmpty()) {
             // no activity found
             return;
         }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index c5f26aa..92f8069 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.res.Resources;
@@ -59,12 +60,11 @@
 import android.view.ViewConfiguration;
 import android.view.animation.Interpolator;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
 import com.android.launcher3.graphics.RotationMode;
 import com.android.launcher3.graphics.TintedDrawableSpan;
 import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.IntArray;
@@ -526,7 +526,7 @@
             boolean flattenDrawable, Object[] outObj) {
         LauncherAppState appState = LauncherAppState.getInstance(launcher);
         if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
-            LauncherActivityInfo activityInfo = LauncherAppsCompat.getInstance(launcher)
+            LauncherActivityInfo activityInfo = launcher.getSystemService(LauncherApps.class)
                     .resolveActivity(info.getIntent(), info.user);
             outObj[0] = activityInfo;
             return (activityInfo != null) ? appState.getIconCache()
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index b25a79b..c5e74ef 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -35,13 +35,13 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.ShadowGenerator;
 import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Executors;
 import com.android.launcher3.util.PackageUserKey;
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
deleted file mode 100644
index 047346d..0000000
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2014 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.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.ShortcutInfo;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.PackageUserKey;
-
-import java.util.List;
-
-public abstract class LauncherAppsCompat {
-
-    public interface OnAppsChangedCallbackCompat {
-        default void onPackageRemoved(String packageName, UserHandle user) { }
-        default void onPackageAdded(String packageName, UserHandle user) { }
-        default void onPackageChanged(String packageName, UserHandle user) { }
-        default void onPackagesAvailable(String[] packageNames, UserHandle user,
-                boolean replacing) { }
-        default void onPackagesUnavailable(String[] packageNames, UserHandle user,
-                boolean replacing) { }
-        default void onPackagesSuspended(String[] packageNames, UserHandle user) { }
-        default void onPackagesUnsuspended(String[] packageNames, UserHandle user) { }
-        default void onShortcutsChanged(String packageName, List<ShortcutInfo> shortcuts,
-                UserHandle user) { }
-    }
-
-    protected LauncherAppsCompat() {
-    }
-
-    private static LauncherAppsCompat sInstance;
-    private static final Object sInstanceLock = new Object();
-
-    public static LauncherAppsCompat getInstance(Context context) {
-        synchronized (sInstanceLock) {
-            if (sInstance == null) {
-                if (Utilities.ATLEAST_OREO) {
-                    sInstance = new LauncherAppsCompatVO(context.getApplicationContext());
-                } else {
-                    sInstance = new LauncherAppsCompatVL(context.getApplicationContext());
-                }
-            }
-            return sInstance;
-        }
-    }
-
-    public abstract List<LauncherActivityInfo> getActivityList(String packageName,
-            UserHandle user);
-    public abstract LauncherActivityInfo resolveActivity(Intent intent,
-            UserHandle user);
-    public abstract void startActivityForProfile(ComponentName component, UserHandle user,
-            Rect sourceBounds, Bundle opts);
-    public abstract ApplicationInfo getApplicationInfo(
-            String packageName, int flags, UserHandle user);
-    public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user,
-            Rect sourceBounds, Bundle opts);
-    public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
-    public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
-    public abstract boolean isPackageEnabledForProfile(String packageName, UserHandle user);
-    public abstract boolean isActivityEnabledForProfile(ComponentName component,
-            UserHandle user);
-    public abstract List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
-            @Nullable PackageUserKey packageUser);
-}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
deleted file mode 100644
index f1b9756..0000000
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2014 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.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-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.Process;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVL;
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.PackageUserKey;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class LauncherAppsCompatVL extends LauncherAppsCompat {
-
-    protected final LauncherApps mLauncherApps;
-    protected final Context mContext;
-
-    private final ArrayMap<OnAppsChangedCallbackCompat, WrappedCallback> mCallbacks =
-        new ArrayMap<>();
-
-    LauncherAppsCompatVL(Context context) {
-        mContext = context;
-        mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
-    }
-
-    @Override
-    public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
-        return mLauncherApps.getActivityList(packageName, user);
-    }
-
-    @Override
-    public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
-        return mLauncherApps.resolveActivity(intent, user);
-    }
-
-    @Override
-    public void startActivityForProfile(ComponentName component, UserHandle user,
-            Rect sourceBounds, Bundle opts) {
-        mLauncherApps.startMainActivity(component, user, sourceBounds, opts);
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
-        final boolean isPrimaryUser = Process.myUserHandle().equals(user);
-        if (!isPrimaryUser && (flags == 0)) {
-            // We are looking for an installed app on a secondary profile. Prior to O, the only
-            // entry point for work profiles is through the LauncherActivity.
-            List<LauncherActivityInfo> activityList =
-                    mLauncherApps.getActivityList(packageName, user);
-            return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
-        }
-        try {
-            ApplicationInfo info =
-                    mContext.getPackageManager().getApplicationInfo(packageName, flags);
-            // There is no way to check if the app is installed for managed profile. But for
-            // primary profile, we can still have this check.
-            if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0)
-                    || !info.enabled) {
-                return null;
-            }
-            return info;
-        } catch (PackageManager.NameNotFoundException e) {
-            // Package not found
-            return null;
-        }
-    }
-
-    @Override
-    public void showAppDetailsForProfile(ComponentName component, UserHandle user,
-            Rect sourceBounds, Bundle opts) {
-        mLauncherApps.startAppDetailsActivity(component, user, sourceBounds, opts);
-    }
-
-    @Override
-    public void addOnAppsChangedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
-        WrappedCallback wrappedCallback = new WrappedCallback(callback);
-        synchronized (mCallbacks) {
-            mCallbacks.put(callback, wrappedCallback);
-        }
-        mLauncherApps.registerCallback(wrappedCallback);
-    }
-
-    @Override
-    public void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) {
-        final WrappedCallback wrappedCallback;
-        synchronized (mCallbacks) {
-            wrappedCallback = mCallbacks.remove(callback);
-        }
-        if (wrappedCallback != null) {
-            mLauncherApps.unregisterCallback(wrappedCallback);
-        }
-    }
-
-    @Override
-    public boolean isPackageEnabledForProfile(String packageName, UserHandle user) {
-        return mLauncherApps.isPackageEnabled(packageName, user);
-    }
-
-    @Override
-    public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) {
-        return mLauncherApps.isActivityEnabled(component, user);
-    }
-
-    private static class WrappedCallback extends LauncherApps.Callback {
-        private final LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
-
-        public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, UserHandle user) {
-            mCallback.onPackageRemoved(packageName, user);
-        }
-
-        @Override
-        public void onPackageAdded(String packageName, UserHandle user) {
-            mCallback.onPackageAdded(packageName, user);
-        }
-
-        @Override
-        public void onPackageChanged(String packageName, UserHandle user) {
-            mCallback.onPackageChanged(packageName, user);
-        }
-
-        @Override
-        public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
-            mCallback.onPackagesAvailable(packageNames, user, replacing);
-        }
-
-        @Override
-        public void onPackagesUnavailable(String[] packageNames, UserHandle user,
-                boolean replacing) {
-            mCallback.onPackagesUnavailable(packageNames, user, replacing);
-        }
-
-        @Override
-        public void onPackagesSuspended(String[] packageNames, UserHandle user) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.APP_NOT_DISABLED, "onPackagesSuspended: " +
-                        Arrays.toString(packageNames));
-            }
-            mCallback.onPackagesSuspended(packageNames, user);
-        }
-
-        @Override
-        public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
-            mCallback.onPackagesUnsuspended(packageNames, user);
-        }
-
-        @Override
-        public void onShortcutsChanged(@NonNull String packageName,
-            @NonNull List<ShortcutInfo> shortcuts,
-            @NonNull UserHandle user) {
-            mCallback.onShortcutsChanged(packageName, shortcuts, user);
-        }
-    }
-
-    @Override
-    public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
-            @Nullable PackageUserKey packageUser) {
-        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
-        if (packageUser != null && !packageUser.mUser.equals(Process.myUserHandle())) {
-            return result;
-        }
-        PackageManager pm = mContext.getPackageManager();
-        for (ResolveInfo info :
-                pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
-            if (packageUser == null || packageUser.mPackageName
-                    .equals(info.activityInfo.packageName)) {
-                result.add(new ShortcutConfigActivityInfoVL(info.activityInfo));
-            }
-        }
-        return result;
-    }
-}
-
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
deleted file mode 100644
index 5e13d00..0000000
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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 static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.LauncherApps;
-import android.content.pm.LauncherApps.PinItemRequest;
-import android.content.pm.PackageManager;
-import android.content.pm.ShortcutInfo;
-import android.os.Build;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.UserHandle;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVO;
-import com.android.launcher3.icons.LauncherIcons;
-import com.android.launcher3.util.PackageUserKey;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@TargetApi(26)
-public class LauncherAppsCompatVO extends LauncherAppsCompatVL {
-
-    LauncherAppsCompatVO(Context context) {
-        super(context);
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
-        try {
-            ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, flags, user);
-            return (info.flags & ApplicationInfo.FLAG_INSTALLED) == 0 || !info.enabled
-                    ? null : info;
-        } catch (PackageManager.NameNotFoundException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
-            @Nullable PackageUserKey packageUser) {
-        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
-        UserHandle myUser = Process.myUserHandle();
-
-        final List<UserHandle> users;
-        final String packageName;
-        if (packageUser == null) {
-            users = UserManagerCompat.getInstance(mContext).getUserProfiles();
-            packageName = null;
-        } else {
-            users = new ArrayList<>(1);
-            users.add(packageUser.mUser);
-            packageName = packageUser.mPackageName;
-        }
-        for (UserHandle user : users) {
-            boolean ignoreTargetSdk = myUser.equals(user);
-            List<LauncherActivityInfo> activities =
-                    mLauncherApps.getShortcutConfigActivityList(packageName, user);
-            for (LauncherActivityInfo activityInfo : activities) {
-                if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion >=
-                        Build.VERSION_CODES.O) {
-                    result.add(new ShortcutConfigActivityInfoVO(activityInfo));
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * request.accept() will initiate the following flow:
-     *      -> go-to-system-process for actual processing (a)
-     *      -> callback-to-launcher on UI thread (b)
-     *      -> post callback on the worker thread (c)
-     *      -> Update model and unpin (in system) any shortcut not in out model. (d)
-     *
-     * Note that (b) will take at-least one frame as it involves posting callback from binder
-     * thread to UI thread.
-     * If (d) happens before we add this shortcut to our model, we will end up unpinning
-     * the shortcut in the system.
-     * Here its the caller's responsibility to add the newly created WorkspaceItemInfo immediately
-     * to the model (which may involves a single post-to-worker-thread). That will guarantee
-     * that (d) happens after model is updated.
-     */
-    @Nullable
-    public static WorkspaceItemInfo createWorkspaceItemFromPinItemRequest(
-            Context context, final PinItemRequest request, final long acceptDelay) {
-        if (request != null &&
-                request.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT &&
-                request.isValid()) {
-
-            if (acceptDelay <= 0) {
-                if (!request.accept()) {
-                    return null;
-                }
-            } else {
-                // Block the worker thread until the accept() is called.
-                MODEL_EXECUTOR.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            Thread.sleep(acceptDelay);
-                        } catch (InterruptedException e) {
-                            // Ignore
-                        }
-                        if (request.isValid()) {
-                            request.accept();
-                        }
-                    }
-                });
-            }
-
-            ShortcutInfo si = request.getShortcutInfo();
-            WorkspaceItemInfo info = new WorkspaceItemInfo(si, context);
-            // Apply the unbadged icon and fetch the actual icon asynchronously.
-            LauncherIcons li = LauncherIcons.obtain(context);
-            info.applyFrom(li.createShortcutIcon(si, false /* badged */));
-            li.recycle();
-            LauncherAppState.getInstance(context).getModel()
-                    .updateAndBindWorkspaceItem(info, si);
-            return info;
-        } else {
-            return null;
-        }
-    }
-
-    public static PinItemRequest getPinItemRequest(Intent intent) {
-        Parcelable extra = intent.getParcelableExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST);
-        return extra instanceof PinItemRequest ? (PinItemRequest) extra : null;
-    }
-}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index b8981b6..1b0567f 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -51,8 +51,8 @@
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.pm.PinRequestHelper;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.InstantAppResolver;
@@ -93,7 +93,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mRequest = LauncherAppsCompatVO.getPinItemRequest(getIntent());
+        mRequest = PinRequestHelper.getPinItemRequest(getIntent());
         if (mRequest == null) {
             finish();
             return;
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index 91a31aa..09062a4 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -29,14 +29,14 @@
 import android.os.Process;
 
 import com.android.launcher3.FastBitmapDrawable;
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherAppsCompatVO;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
+import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.pm.PinRequestHelper;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 
 /**
  * Extension of ShortcutConfigActivityInfo to be used in the confirmation prompt for pin item
@@ -88,7 +88,7 @@
                 LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY +
                 LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS;
         // Delay the actual accept() call until the drop animation is complete.
-        return LauncherAppsCompatVO.createWorkspaceItemFromPinItemRequest(
+        return PinRequestHelper.createWorkspaceItemFromPinItemRequest(
                 mContext, mRequest, duration);
     }
 
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index b1818a0..9886f53 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
@@ -42,7 +43,6 @@
 import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
@@ -66,7 +66,7 @@
     private final CachingLogic<ComponentWithLabel> mComponentWithLabelCachingLogic;
     private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic;
 
-    private final LauncherAppsCompat mLauncherApps;
+    private final LauncherApps mLauncherApps;
     private final UserManagerCompat mUserManager;
     private final InstantAppResolver mInstantAppResolver;
     private final IconProvider mIconProvider;
@@ -78,7 +78,7 @@
                 inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */);
         mComponentWithLabelCachingLogic = new ComponentCachingLogic(context, false);
         mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.newInstance(context);
-        mLauncherApps = LauncherAppsCompat.getInstance(mContext);
+        mLauncherApps = mContext.getSystemService(LauncherApps.class);
         mUserManager = UserManagerCompat.getInstance(mContext);
         mInstantAppResolver = InstantAppResolver.newInstance(mContext);
         mIconProvider = IconProvider.INSTANCE.get(context);
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 844a2a6..227bb22 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -17,6 +17,7 @@
 
 import android.content.Intent;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.os.UserHandle;
 import android.util.LongSparseArray;
@@ -31,7 +32,6 @@
 import com.android.launcher3.LauncherModel.CallbackTask;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.pm.PackageInstallerCompat;
 import com.android.launcher3.util.GridOccupancy;
@@ -90,7 +90,7 @@
 
             PackageInstallerCompat packageInstaller =
                     PackageInstallerCompat.getInstance(app.getContext());
-            LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(app.getContext());
+            LauncherApps launcherApps = app.getContext().getSystemService(LauncherApps.class);
 
             for (ItemInfo item : filteredItems) {
                 // Find appropriate space for the item.
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 1e1df88..9f1843f 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.os.LocaleList;
 import android.os.Process;
 import android.os.UserHandle;
@@ -35,11 +36,11 @@
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.PromiseAppInfo;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.pm.PackageInstallInfo;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.SafeCloseable;
 
 import java.util.ArrayList;
@@ -110,8 +111,8 @@
     }
 
     public void addPromiseApp(Context context, PackageInstallInfo installInfo) {
-        ApplicationInfo applicationInfo = LauncherAppsCompat.getInstance(context)
-                .getApplicationInfo(installInfo.packageName, 0, installInfo.user);
+        ApplicationInfo applicationInfo = new PackageManagerHelper(context)
+                .getApplicationInfo(installInfo.packageName, installInfo.user, 0);
         // only if not yet installed
         if (applicationInfo == null) {
             PromiseAppInfo info = new PromiseAppInfo(installInfo);
@@ -162,11 +163,8 @@
      * Add the icons for the supplied apk called packageName.
      */
     public void addPackage(Context context, String packageName, UserHandle user) {
-        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-        final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
-                user);
-
-        for (LauncherActivityInfo info : matches) {
+        for (LauncherActivityInfo info : context.getSystemService(LauncherApps.class)
+                .getActivityList(packageName, user)) {
             add(new AppInfo(context, info, user), info);
         }
     }
@@ -212,9 +210,8 @@
      * Add and remove icons for this package which has been updated.
      */
     public void updatePackage(Context context, String packageName, UserHandle user) {
-        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-        final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
-                user);
+        final List<LauncherActivityInfo> matches = context.getSystemService(LauncherApps.class)
+                .getActivityList(packageName, user);
         if (matches.size() > 0) {
             // Find disabled/removed activities and remove them from data and add them
             // to the removed list.
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 1c39d1f..6154e7e 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.Intent.ShortcutIconResource;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.database.CursorWrapper;
@@ -33,17 +34,16 @@
 import android.util.LongSparseArray;
 
 import com.android.launcher3.AppInfo;
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
-import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.WorkspaceItemInfo;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.ContentWriter;
@@ -260,7 +260,7 @@
         Intent newIntent = new Intent(Intent.ACTION_MAIN, null);
         newIntent.addCategory(Intent.CATEGORY_LAUNCHER);
         newIntent.setComponent(componentName);
-        LauncherActivityInfo lai = LauncherAppsCompat.getInstance(mContext)
+        LauncherActivityInfo lai = mContext.getSystemService(LauncherApps.class)
                 .resolveActivity(newIntent, user);
         if ((lai == null) && !allowMissingTarget) {
             Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName);
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 97cf846..a29b7e1 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.ShortcutInfo;
@@ -52,7 +53,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.WorkspaceItemInfo;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.Folder;
@@ -105,7 +105,7 @@
 
     private final LoaderResults mResults;
 
-    private final LauncherAppsCompat mLauncherApps;
+    private final LauncherApps mLauncherApps;
     private final UserManagerCompat mUserManager;
     private final DeepShortcutManager mShortcutManager;
     private final PackageInstallerCompat mPackageInstaller;
@@ -121,7 +121,7 @@
         mBgDataModel = dataModel;
         mResults = results;
 
-        mLauncherApps = LauncherAppsCompat.getInstance(mApp.getContext());
+        mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);
         mUserManager = UserManagerCompat.getInstance(mApp.getContext());
         mShortcutManager = DeepShortcutManager.getInstance(mApp.getContext());
         mPackageInstaller = PackageInstallerCompat.getInstance(mApp.getContext());
@@ -390,7 +390,7 @@
                             // If there is no target package, its an implicit intent
                             // (legacy shortcut) which is always valid
                             boolean validTarget = TextUtils.isEmpty(targetPkg) ||
-                                    mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
+                                    mLauncherApps.isPackageEnabled(targetPkg, c.user);
 
                             // If it's a deep shortcut, we'll use pinned shortcuts to restore it
                             if (cn != null && validTarget && c.itemType
@@ -399,7 +399,7 @@
                                 // component.
 
                                 // If the component is already present
-                                if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
+                                if (mLauncherApps.isActivityEnabled(cn, c.user)) {
                                     // no special handling necessary for this item
                                     c.markRestored();
                                 } else {
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 7ea310c..db63b7c 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -16,10 +16,12 @@
 package com.android.launcher3.model;
 
 import static com.android.launcher3.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
+import static com.android.launcher3.WorkspaceItemInfo.FLAG_RESTORED_ICON;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherApps;
 import android.content.pm.ShortcutInfo;
 import android.os.Process;
 import android.os.UserHandle;
@@ -33,7 +35,6 @@
 import com.android.launcher3.SessionCommitReceiver;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.BitmapInfo;
@@ -55,9 +56,6 @@
 import java.util.HashSet;
 import java.util.List;
 
-import static com.android.launcher3.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
-import static com.android.launcher3.WorkspaceItemInfo.FLAG_RESTORED_ICON;
-
 /**
  * Handles updates due to changes in package manager (app installed/updated/removed)
  * or when a user availability changes.
@@ -221,8 +219,8 @@
                                         infoUpdated = true;
                                     }
                                 } else if (!cn.getClassName().equals(IconCache.EMPTY_CLASS_NAME)) {
-                                    isTargetValid = LauncherAppsCompat.getInstance(context)
-                                            .isActivityEnabledForProfile(cn, mUser);
+                                    isTargetValid = context.getSystemService(LauncherApps.class)
+                                            .isActivityEnabled(cn, mUser);
                                 }
                                 if (si.hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)) {
                                     if (updateWorkspaceItemIntent(context, si, packageName)) {
@@ -305,9 +303,9 @@
             // removedPackages is a super-set of removedComponents
         } else if (mOp == OP_UPDATE) {
             // Mark disabled packages in the broadcast to be removed
-            final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+            final LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
             for (int i=0; i<N; i++) {
-                if (!launcherApps.isPackageEnabledForProfile(packages[i], mUser)) {
+                if (!launcherApps.isPackageEnabled(packages[i], mUser)) {
                     removedPackages.add(packages[i]);
                 }
             }
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index 3aedae6..eb3cb52 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -19,11 +19,11 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherApps;
 import android.os.UserHandle;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageManagerHelper;
 
@@ -53,7 +53,7 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+        final LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
         final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
         for (Entry<UserHandle, ArrayList<String>> entry : mPackages.entrySet()) {
             UserHandle user = entry.getKey();
@@ -62,7 +62,7 @@
             final ArrayList<String> packagesUnavailable = new ArrayList<>();
 
             for (String pkg : new HashSet<>(entry.getValue())) {
-                if (!launcherApps.isPackageEnabledForProfile(pkg, user)) {
+                if (!launcherApps.isPackageEnabled(pkg, user)) {
                     if (pmHelper.isAppOnSdcard(pkg, user)) {
                         packagesUnavailable.add(pkg);
                     } else {
diff --git a/src/com/android/launcher3/model/WidgetItem.java b/src/com/android/launcher3/model/WidgetItem.java
index e38529b..b442c42 100644
--- a/src/com/android/launcher3/model/WidgetItem.java
+++ b/src/com/android/launcher3/model/WidgetItem.java
@@ -8,8 +8,8 @@
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 import com.android.launcher3.util.ComponentKey;
 
 import java.text.Collator;
diff --git a/src/com/android/launcher3/pm/PackageInstallerCompat.java b/src/com/android/launcher3/pm/PackageInstallerCompat.java
index 520c207..c7b27d9 100644
--- a/src/com/android/launcher3/pm/PackageInstallerCompat.java
+++ b/src/com/android/launcher3/pm/PackageInstallerCompat.java
@@ -31,11 +31,11 @@
 
 import com.android.launcher3.SessionCommitReceiver;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.util.ArrayList;
@@ -103,8 +103,8 @@
     public HashMap<PackageUserKey, SessionInfo> getActiveSessions() {
         HashMap<PackageUserKey, SessionInfo> activePackages = new HashMap<>();
         for (SessionInfo info : getAllVerifiedSessions()) {
-            activePackages.put(
-                    new PackageUserKey(info.getAppPackageName(), getUserHandle(info)), info);
+            activePackages.put(new PackageUserKey(info.getAppPackageName(), getUserHandle(info)),
+                    info);
         }
         return activePackages;
     }
@@ -141,9 +141,8 @@
         String pkg = sessionInfo.getInstallerPackageName();
         synchronized (mSessionVerifiedMap) {
             if (!mSessionVerifiedMap.containsKey(pkg)) {
-                LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mAppContext);
-                boolean hasSystemFlag = launcherApps.getApplicationInfo(pkg,
-                        ApplicationInfo.FLAG_SYSTEM, getUserHandle(sessionInfo)) != null;
+                boolean hasSystemFlag = new PackageManagerHelper(mAppContext).getApplicationInfo(
+                        pkg, getUserHandle(sessionInfo), ApplicationInfo.FLAG_SYSTEM) != null;
                 mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
             }
         }
@@ -190,8 +189,8 @@
                 && sessionInfo.getAppIcon() != null
                 && !TextUtils.isEmpty(sessionInfo.getAppLabel())
                 && !mPromiseIconIds.contains(sessionInfo.getSessionId())
-                && LauncherAppsCompat.getInstance(mAppContext).getApplicationInfo(
-                        sessionInfo.getAppPackageName(), 0, getUserHandle(sessionInfo)) == null) {
+                && new PackageManagerHelper(mAppContext).getApplicationInfo(
+                        sessionInfo.getAppPackageName(), getUserHandle(sessionInfo), 0) == null) {
             SessionCommitReceiver.queuePromiseAppIconAddition(mAppContext, sessionInfo);
             mPromiseIconIds.add(sessionInfo.getSessionId());
             updatePromiseIconPrefs();
diff --git a/src/com/android/launcher3/pm/PinRequestHelper.java b/src/com/android/launcher3/pm/PinRequestHelper.java
new file mode 100644
index 0000000..68ea6c4
--- /dev/null
+++ b/src/com/android/launcher3/pm/PinRequestHelper.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 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.pm;
+
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.PinItemRequest;
+import android.content.pm.ShortcutInfo;
+import android.os.Build;
+import android.os.Parcelable;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.icons.LauncherIcons;
+
+public class PinRequestHelper {
+
+    /**
+     * request.accept() will initiate the following flow:
+     *      -> go-to-system-process for actual processing (a)
+     *      -> callback-to-launcher on UI thread (b)
+     *      -> post callback on the worker thread (c)
+     *      -> Update model and unpin (in system) any shortcut not in out model. (d)
+     *
+     * Note that (b) will take at-least one frame as it involves posting callback from binder
+     * thread to UI thread.
+     * If (d) happens before we add this shortcut to our model, we will end up unpinning
+     * the shortcut in the system.
+     * Here its the caller's responsibility to add the newly created WorkspaceItemInfo immediately
+     * to the model (which may involves a single post-to-worker-thread). That will guarantee
+     * that (d) happens after model is updated.
+     */
+    @Nullable
+    @TargetApi(Build.VERSION_CODES.O)
+    public static WorkspaceItemInfo createWorkspaceItemFromPinItemRequest(
+            Context context, final PinItemRequest request, final long acceptDelay) {
+        if (request != null && request.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT
+                && request.isValid()) {
+
+            if (acceptDelay <= 0) {
+                if (!request.accept()) {
+                    return null;
+                }
+            } else {
+                // Block the worker thread until the accept() is called.
+                MODEL_EXECUTOR.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            Thread.sleep(acceptDelay);
+                        } catch (InterruptedException e) {
+                            // Ignore
+                        }
+                        if (request.isValid()) {
+                            request.accept();
+                        }
+                    }
+                });
+            }
+
+            ShortcutInfo si = request.getShortcutInfo();
+            WorkspaceItemInfo info = new WorkspaceItemInfo(si, context);
+            // Apply the unbadged icon and fetch the actual icon asynchronously.
+            LauncherIcons li = LauncherIcons.obtain(context);
+            info.applyFrom(li.createShortcutIcon(si, false /* badged */));
+            li.recycle();
+            LauncherAppState.getInstance(context).getModel()
+                    .updateAndBindWorkspaceItem(info, si);
+            return info;
+        } else {
+            return null;
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.O)
+    public static PinItemRequest getPinItemRequest(Intent intent) {
+        Parcelable extra = intent.getParcelableExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST);
+        return extra instanceof PinItemRequest ? (PinItemRequest) extra : null;
+    }
+}
diff --git a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
similarity index 66%
rename from src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
rename to src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
index ace5691..0922e41 100644
--- a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/pm/ShortcutConfigActivityInfo.java
@@ -14,29 +14,40 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.compat;
+package com.android.launcher3.pm;
 
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
+import android.content.Context;
 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.Build;
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
 import android.widget.Toast;
 
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.icons.ComponentWithLabel;
-import com.android.launcher3.icons.IconCache;
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.util.PackageUserKey;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Wrapper class for representing a shortcut configure activity.
@@ -87,9 +98,9 @@
             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);
+            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;
     }
@@ -106,7 +117,7 @@
 
         private final ActivityInfo mInfo;
 
-        public ShortcutConfigActivityInfoVL(ActivityInfo info) {
+        ShortcutConfigActivityInfoVL(ActivityInfo info) {
             super(new ComponentName(info.packageName, info.name), Process.myUserHandle());
             mInfo = info;
         }
@@ -158,4 +169,46 @@
             }
         }
     }
+
+    public static List<ShortcutConfigActivityInfo> queryList(
+            Context context, @Nullable PackageUserKey packageUser) {
+        List<ShortcutConfigActivityInfo> result = new ArrayList<>();
+        UserHandle myUser = Process.myUserHandle();
+
+        if (Utilities.ATLEAST_OREO) {
+            final List<UserHandle> users;
+            final String packageName;
+            if (packageUser == null) {
+                users = UserManagerCompat.getInstance(context).getUserProfiles();
+                packageName = null;
+            } else {
+                users = new ArrayList<>(1);
+                users.add(packageUser.mUser);
+                packageName = packageUser.mPackageName;
+            }
+            LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
+            for (UserHandle user : users) {
+                boolean ignoreTargetSdk = myUser.equals(user);
+                for (LauncherActivityInfo activityInfo :
+                        launcherApps.getShortcutConfigActivityList(packageName, user)) {
+                    if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion
+                            >= Build.VERSION_CODES.O) {
+                        result.add(new ShortcutConfigActivityInfoVO(activityInfo));
+                    }
+                }
+            }
+        } else {
+            if (packageUser == null || packageUser.mUser.equals(myUser)) {
+                Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+                if (packageUser != null) {
+                    intent.setPackage(packageUser.mPackageName);
+                }
+                for (ResolveInfo info :
+                        context.getPackageManager().queryIntentActivities(intent, 0)) {
+                    result.add(new ShortcutConfigActivityInfoVL(info.activityInfo));
+                }
+            }
+        }
+        return result;
+    }
 }
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index ef4307e..7b4e0c6 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -24,6 +24,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -34,6 +35,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.PatternMatcher;
+import android.os.Process;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
@@ -46,8 +48,8 @@
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.PromiseAppInfo;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.compat.LauncherAppsCompat;
 
 import java.net.URISyntaxException;
 import java.util.List;
@@ -61,12 +63,12 @@
 
     private final Context mContext;
     private final PackageManager mPm;
-    private final LauncherAppsCompat mLauncherApps;
+    private final LauncherApps mLauncherApps;
 
     public PackageManagerHelper(Context context) {
         mContext = context;
         mPm = context.getPackageManager();
-        mLauncherApps = LauncherAppsCompat.getInstance(context);
+        mLauncherApps = context.getSystemService(LauncherApps.class);
     }
 
     /**
@@ -74,8 +76,8 @@
      * guarantee that the app is on SD card.
      */
     public boolean isAppOnSdcard(String packageName, UserHandle user) {
-        ApplicationInfo info = mLauncherApps.getApplicationInfo(
-                packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, user);
+        ApplicationInfo info = getApplicationInfo(
+                packageName, user, PackageManager.MATCH_UNINSTALLED_PACKAGES);
         return info != null && (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
     }
 
@@ -84,10 +86,47 @@
      * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
      */
     public boolean isAppSuspended(String packageName, UserHandle user) {
-        ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, 0, user);
+        ApplicationInfo info = getApplicationInfo(packageName, user, 0);
         return info != null && isAppSuspended(info);
     }
 
+    /**
+     * Returns the application info for the provided package or null
+     */
+    public ApplicationInfo getApplicationInfo(String packageName, UserHandle user, int flags) {
+        if (Utilities.ATLEAST_OREO) {
+            try {
+                ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, flags, user);
+                return (info.flags & ApplicationInfo.FLAG_INSTALLED) == 0 || !info.enabled
+                        ? null : info;
+            } catch (PackageManager.NameNotFoundException e) {
+                return null;
+            }
+        } else {
+            final boolean isPrimaryUser = Process.myUserHandle().equals(user);
+            if (!isPrimaryUser && (flags == 0)) {
+                // We are looking for an installed app on a secondary profile. Prior to O, the only
+                // entry point for work profiles is through the LauncherActivity.
+                List<LauncherActivityInfo> activityList =
+                        mLauncherApps.getActivityList(packageName, user);
+                return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
+            }
+            try {
+                ApplicationInfo info = mPm.getApplicationInfo(packageName, flags);
+                // There is no way to check if the app is installed for managed profile. But for
+                // primary profile, we can still have this check.
+                if (isPrimaryUser && ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0)
+                        || !info.enabled) {
+                    return null;
+                }
+                return info;
+            } catch (PackageManager.NameNotFoundException e) {
+                // Package not found
+                return null;
+            }
+        }
+    }
+
     public boolean isSafeMode() {
         return mContext.getPackageManager().isSafeMode();
     }
@@ -202,8 +241,7 @@
         }
         if (componentName != null) {
             try {
-                mLauncherApps.showAppDetailsForProfile(
-                        componentName, info.user, sourceBounds, opts);
+                mLauncherApps.startAppDetailsActivity(componentName, info.user, sourceBounds, opts);
             } catch (SecurityException | ActivityNotFoundException e) {
                 Toast.makeText(mContext, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                 Log.e(TAG, "Unable to launch settings", e);
diff --git a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
new file mode 100644
index 0000000..465a0e8
--- /dev/null
+++ b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 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.util;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import java.util.function.Consumer;
+
+public class SimpleBroadcastReceiver extends BroadcastReceiver {
+
+    private final Consumer<Intent> mIntentConsumer;
+
+    public SimpleBroadcastReceiver(Consumer<Intent> intentConsumer) {
+        mIntentConsumer = intentConsumer;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        mIntentConsumer.accept(intent);
+    }
+
+    /**
+     * Helper method to register multiple actions
+     */
+    public void register(Context context, String... actions) {
+        IntentFilter filter = new IntentFilter();
+        for (String action : actions) {
+            filter.addAction(action);
+        }
+        context.registerReceiver(this, filter);
+    }
+}
diff --git a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
index 62b6903..6e21a41 100644
--- a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
@@ -16,7 +16,7 @@
 package com.android.launcher3.widget;
 
 import com.android.launcher3.PendingAddItemInfo;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 
 /**
  * Meta data used for late binding of the short cuts.
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 0f6ad27..b8af8ed 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -3,6 +3,8 @@
 
 import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER;
 
+import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList;
+
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -10,6 +12,8 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.AppFilter;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
@@ -17,11 +21,10 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.ComponentWithLabel;
 import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
@@ -37,8 +40,6 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
-import androidx.annotation.Nullable;
-
 /**
  * Widgets data model that is used by the adapters of the widget views and controllers.
  *
@@ -106,8 +107,8 @@
             }
 
             // Shortcuts
-            for (ShortcutConfigActivityInfo info : LauncherAppsCompat.getInstance(context)
-                    .getCustomShortcutActivityList(packageUser)) {
+            for (ShortcutConfigActivityInfo info :
+                    queryList(context, packageUser)) {
                 widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
                 updatedItems.add(info);
             }
diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
index 64df8e0..7029ad5 100644
--- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -1,29 +1,5 @@
 package com.android.launcher3.model;
 
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.os.Process;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.util.PackageManagerHelper;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static com.android.launcher3.LauncherSettings.Favorites.INTENT;
 import static com.android.launcher3.LauncherSettings.Favorites.CELLX;
 import static com.android.launcher3.LauncherSettings.Favorites.CELLY;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER;
@@ -32,6 +8,7 @@
 import static com.android.launcher3.LauncherSettings.Favorites.ICON;
 import static com.android.launcher3.LauncherSettings.Favorites.ICON_PACKAGE;
 import static com.android.launcher3.LauncherSettings.Favorites.ICON_RESOURCE;
+import static com.android.launcher3.LauncherSettings.Favorites.INTENT;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
@@ -40,15 +17,41 @@
 import static com.android.launcher3.LauncherSettings.Favorites.SCREEN;
 import static com.android.launcher3.LauncherSettings.Favorites.TITLE;
 import static com.android.launcher3.LauncherSettings.Favorites._ID;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.os.Process;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.util.PackageManagerHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests for {@link LoaderCursor}
  */
@@ -62,7 +65,7 @@
     private MatrixCursor mCursor;
     private InvariantDeviceProfile mIDP;
     private Context mContext;
-    private LauncherAppsCompat mLauncherApps;
+    private LauncherApps mLauncherApps;
 
     private LoaderCursor mLoaderCursor;
 
@@ -81,7 +84,7 @@
         when(mMockApp.getIconCache()).thenReturn(mMockIconCache);
         when(mMockApp.getInvariantDeviceProfile()).thenReturn(mIDP);
         when(mMockApp.getContext()).thenReturn(mContext);
-        mLauncherApps = LauncherAppsCompat.getInstance(mContext);
+        mLauncherApps = mContext.getSystemService(LauncherApps.class);
 
         mLoaderCursor = new LoaderCursor(mCursor, mMockApp);
         mLoaderCursor.allUsers.put(0, Process.myUserHandle());
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5bedd62..62989a3 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -34,6 +34,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.os.Process;
 import android.os.RemoteException;
@@ -52,7 +53,6 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.model.AppLaunchTracker;
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.tapl.TestHelpers;
@@ -335,9 +335,8 @@
     }
 
     protected LauncherActivityInfo getSettingsApp() {
-        return LauncherAppsCompat.getInstance(mTargetContext)
-                .getActivityList("com.android.settings",
-                        Process.myUserHandle()).get(0);
+        return mTargetContext.getSystemService(LauncherApps.class)
+                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
     }
 
     /**