Merge "Adds StatusBarNotificationActivityStarterTest"
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java
new file mode 100644
index 0000000..2b62e04
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ActivityIntentHelper.java
@@ -0,0 +1,119 @@
+/*
+ * 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.systemui;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+import java.util.List;
+
+/**
+ * Contains useful methods for querying properties of an Activity Intent.
+ */
+public class ActivityIntentHelper {
+
+    private final Context mContext;
+
+    public ActivityIntentHelper(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Determines if sending the given intent would result in starting an Intent resolver activity,
+     * instead of resolving to a specific component.
+     *
+     * @param intent the intent
+     * @param currentUserId the id for the user to resolve as
+     * @return true if the intent would launch a resolver activity
+     */
+    public boolean wouldLaunchResolverActivity(Intent intent, int currentUserId) {
+        ActivityInfo targetActivityInfo = getTargetActivityInfo(intent, currentUserId,
+                false /* onlyDirectBootAware */);
+        return targetActivityInfo == null;
+    }
+
+    /**
+     * Returns info about the target Activity of a given intent, or null if the intent does not
+     * resolve to a specific component meeting the requirements.
+     *
+     * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must
+     *         be direct boot aware when in direct boot mode if false, all packages are considered
+     *         a match even if they are not aware.
+     * @return the target activity info of the intent it resolves to a specific package or
+     *         {@code null} if it resolved to the resolver activity
+     */
+    public ActivityInfo getTargetActivityInfo(Intent intent, int currentUserId,
+            boolean onlyDirectBootAware) {
+        PackageManager packageManager = mContext.getPackageManager();
+        int flags = PackageManager.MATCH_DEFAULT_ONLY;
+        if (!onlyDirectBootAware) {
+            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE
+                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+        }
+        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+                intent, flags, currentUserId);
+        if (appList.size() == 0) {
+            return null;
+        }
+        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+                flags | PackageManager.GET_META_DATA, currentUserId);
+        if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
+            return null;
+        } else {
+            return resolved.activityInfo;
+        }
+    }
+
+    /**
+     * Determines if the given intent resolves to an Activity which is allowed to appear above
+     * the lock screen.
+     *
+     * @param intent the intent to resolve
+     * @return true if the launched Activity would appear above the lock screen
+     */
+    public boolean wouldShowOverLockscreen(Intent intent, int currentUserId) {
+        ActivityInfo targetActivityInfo = getTargetActivityInfo(intent,
+                currentUserId, false /* onlyDirectBootAware */);
+        return targetActivityInfo != null
+                && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED
+                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
+    }
+
+    /**
+     * Determines if sending the given intent would result in starting an Intent resolver activity,
+     * instead of resolving to a specific component.
+     *
+     * @param resolved the resolveInfo for the intent as returned by resolveActivityAsUser
+     * @param appList a list of resolveInfo as returned by queryIntentActivitiesAsUser
+     * @return true if the intent would launch a resolver activity
+     */
+    public boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
+        // If the list contains the above resolved activity, then it can't be
+        // ResolverActivity itself.
+        for (int i = 0; i < appList.size(); i++) {
+            ResolveInfo tmp = appList.get(i);
+            if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+                    && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 847f3ff..800ae58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -67,6 +67,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -170,6 +171,7 @@
     private boolean mDozing;
     private int mIndicationBottomMargin;
     private float mDarkAmount;
+    private ActivityIntentHelper mActivityIntentHelper;
 
     public KeyguardBottomAreaView(Context context) {
         this(context, null);
@@ -235,6 +237,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mLockPatternUtils = new LockPatternUtils(mContext);
+        mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext),
+                new ActivityIntentHelper(mContext));
         mPreviewContainer = findViewById(R.id.preview_container);
         mOverlayContainer = findViewById(R.id.overlay_container);
         mRightAffordanceView = findViewById(R.id.camera_button);
@@ -254,7 +258,6 @@
         mLockIcon.update();
         setClipChildren(false);
         setClipToPadding(false);
-        mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
         inflateCameraPreview();
         mLockIcon.setOnClickListener(this);
         mLockIcon.setOnLongClickListener(this);
@@ -266,6 +269,7 @@
         mAccessibilityController = Dependency.get(AccessibilityController.class);
         mAssistManager = Dependency.get(AssistManager.class);
         mLockIcon.setAccessibilityController(mAccessibilityController);
+        mActivityIntentHelper = new ActivityIntentHelper(getContext());
         updateLeftAffordance();
     }
 
@@ -459,7 +463,7 @@
 
     public void bindCameraPrewarmService() {
         Intent intent = getCameraIntent();
-        ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent,
+        ActivityInfo targetInfo = mActivityIntentHelper.getTargetActivityInfo(intent,
                 KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
         if (targetInfo != null && targetInfo.metaData != null) {
             String clazz = targetInfo.metaData.getString(
@@ -500,8 +504,8 @@
     public void launchCamera(String source) {
         final Intent intent = getCameraIntent();
         intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
-        boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
-                mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
+        boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity(
+                intent, KeyguardUpdateMonitor.getCurrentUser());
         if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
             AsyncTask.execute(new Runnable() {
                 @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 319a504..5d52359 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,6 +25,7 @@
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 
+import static com.android.systemui.Dependency.MAIN_HANDLER;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
@@ -126,6 +127,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.ActivityStarterDelegate;
 import com.android.systemui.AutoReinflateContainer;
 import com.android.systemui.DemoMode;
@@ -219,7 +221,6 @@
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
-import com.android.systemui.statusbar.policy.PreviewInflater;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
@@ -586,11 +587,12 @@
                 mEntryManager.updateNotifications();
                 updateScrimController();
             };
+    private ActivityIntentHelper mActivityIntentHelper;
 
     @Override
     public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
         mForegroundServiceController.onAppOpChanged(code, uid, packageName, active);
-        Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
+        Dependency.get(MAIN_HANDLER).post(() -> {
             mNotificationListController.updateNotificationsForAppOp(code, uid, packageName, active);
         });
     }
@@ -635,6 +637,7 @@
         mNavigationBarController = Dependency.get(NavigationBarController.class);
         mBubbleController = Dependency.get(BubbleController.class);
         mBubbleController.setExpandListener(mBubbleExpandListener);
+        mActivityIntentHelper = new ActivityIntentHelper(mContext);
         KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
         if (sliceProvider != null) {
             sliceProvider.initDependencies(mMediaManager, mStatusBarStateController);
@@ -1069,7 +1072,8 @@
                 mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager,
                 mLockscreenUserManager, shadeController, mKeyguardMonitor,
                 mNotificationInterruptionStateProvider, mMetricsLogger,
-                new LockPatternUtils(mContext));
+                new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
+                mActivityIntentHelper);
 
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
 
@@ -2449,8 +2453,8 @@
             final Callback callback, int flags) {
         if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
 
-        final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
-                mContext, intent, mLockscreenUserManager.getCurrentUserId());
+        final boolean afterKeyguardGone = mActivityIntentHelper.wouldLaunchResolverActivity(
+                intent, mLockscreenUserManager.getCurrentUserId());
         Runnable runnable = () -> {
             mAssistManager.hideAssist();
             intent.setFlags(
@@ -4315,7 +4319,7 @@
     public void startPendingIntentDismissingKeyguard(
             final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
         final boolean afterKeyguardGone = intent.isActivity()
-                && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
+                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
 
         executeActionDismissingKeyguard(() -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 7e45507..215f5c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.Dependency.MAIN_HANDLER;
 import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions;
 
 import android.app.ActivityManager;
@@ -29,6 +28,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncTask;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -43,6 +43,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.Dependency;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.UiOffloadThread;
@@ -65,7 +66,6 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import com.android.systemui.statusbar.policy.PreviewInflater;
 
 /**
  * Status bar implementation of {@link NotificationActivityStarter}.
@@ -97,6 +97,8 @@
     private final IStatusBarService mBarService;
     private final CommandQueue mCommandQueue;
     private final IDreamManager mDreamManager;
+    private final Handler mMainThreadHandler;
+    private final ActivityIntentHelper mActivityIntentHelper;
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
 
@@ -121,7 +123,9 @@
             KeyguardMonitor keyguardMonitor,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             MetricsLogger metricsLogger,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils,
+            Handler mainThreadHandler,
+            ActivityIntentHelper activityIntentHelper) {
         mContext = context;
         mNotificationPanel = panel;
         mPresenter = presenter;
@@ -150,6 +154,8 @@
             }
         });
         mStatusBarRemoteInputCallback = remoteInputCallback;
+        mMainThreadHandler = mainThreadHandler;
+        mActivityIntentHelper = activityIntentHelper;
     }
 
     /**
@@ -176,12 +182,11 @@
 
         boolean isActivityIntent = intent.isActivity();
         final boolean afterKeyguardGone = isActivityIntent
-                && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
+                && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
         final boolean wasOccluded = mShadeController.isOccluded();
         boolean showOverLockscreen = mKeyguardMonitor.isShowing()
-                && PreviewInflater.wouldShowOverLockscreen(mContext,
-                intent.getIntent(),
+                && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
         ActivityStarter.OnDismissAction postKeyguardAction =
                 () -> handleNotificationClickAfterKeyguardDismissed(
@@ -358,7 +363,7 @@
                 mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
                 if (shouldCollapse()) {
                     // Putting it back on the main thread, since we're touching views
-                    Dependency.get(MAIN_HANDLER).post(() -> mCommandQueue.animateCollapsePanels(
+                    mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels(
                             CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
                 }
             });
@@ -425,7 +430,7 @@
         if (Looper.getMainLooper().isCurrentThread()) {
             mShadeController.collapsePanel();
         } else {
-            Dependency.get(MAIN_HANDLER).post(mShadeController::collapsePanel);
+            mMainThreadHandler.post(mShadeController::collapsePanel);
         }
     }
 
@@ -444,7 +449,7 @@
 
     private void removeNotification(StatusBarNotification notification) {
         // We have to post it to the UI thread for synchronization
-        Dependency.get(MAIN_HANDLER).post(() -> {
+        mMainThreadHandler.post(() -> {
             Runnable removeRunnable =
                     () -> mEntryManager.performRemoveNotification(notification);
             if (mPresenter.isCollapsing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 21d9dcc..471d511 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -33,6 +33,7 @@
 import android.view.View;
 import android.view.ViewParent;
 
+import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -46,7 +47,6 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import com.android.systemui.statusbar.policy.PreviewInflater;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -64,6 +64,7 @@
             Dependency.get(NotificationLockscreenUserManager.class);
     private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
     private final Context mContext;
+    private final ActivityIntentHelper mActivityIntentHelper;
     private View mPendingWorkRemoteInputView;
     private View mPendingRemoteInputView;
     private final ShadeController mShadeController = Dependency.get(ShadeController.class);
@@ -83,6 +84,7 @@
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
         mCommandQueue = getComponent(context, CommandQueue.class);
         mCommandQueue.addCallback(this);
+        mActivityIntentHelper = new ActivityIntentHelper(mContext);
     }
 
     @Override
@@ -220,8 +222,8 @@
             NotificationRemoteInputManager.ClickHandler defaultHandler) {
         final boolean isActivity = pendingIntent.isActivity();
         if (isActivity) {
-            final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
-                    mContext, pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId());
+            final boolean afterKeyguardGone = mActivityIntentHelper.wouldLaunchResolverActivity(
+                    pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId());
             mActivityStarter.dismissKeyguardThenExecute(() -> {
                 try {
                     ActivityManager.getService().resumeAppSwitches();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index 92034b2..3d31714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -19,7 +19,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
@@ -29,6 +28,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
 
 import java.util.List;
@@ -41,13 +41,16 @@
     private static final String TAG = "PreviewInflater";
 
     private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
+    private final ActivityIntentHelper mActivityIntentHelper;
 
     private Context mContext;
     private LockPatternUtils mLockPatternUtils;
 
-    public PreviewInflater(Context context, LockPatternUtils lockPatternUtils) {
+    public PreviewInflater(Context context, LockPatternUtils lockPatternUtils,
+            ActivityIntentHelper activityIntentHelper) {
         mContext = context;
         mLockPatternUtils = lockPatternUtils;
+        mActivityIntentHelper = activityIntentHelper;
     }
 
     public View inflatePreview(Intent intent) {
@@ -130,7 +133,7 @@
         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
                 flags | PackageManager.GET_META_DATA,
                 KeyguardUpdateMonitor.getCurrentUser());
-        if (wouldLaunchResolverActivity(resolved, appList)) {
+        if (mActivityIntentHelper.wouldLaunchResolverActivity(resolved, appList)) {
             return null;
         }
         if (resolved == null || resolved.activityInfo == null) {
@@ -140,63 +143,6 @@
                 resolved.activityInfo.metaData);
     }
 
-    public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent,
-            int currentUserId) {
-        return getTargetActivityInfo(ctx, intent, currentUserId, false /* onlyDirectBootAware */)
-                == null;
-    }
-
-    public static boolean wouldShowOverLockscreen(Context ctx, Intent intent, int currentUserId) {
-        ActivityInfo targetActivityInfo = getTargetActivityInfo(ctx, intent, currentUserId,
-                false /* onlyDirectBootAware */);
-        return targetActivityInfo != null
-                && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED
-                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
-    }
-
-    /**
-     * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must
-     *                            be direct boot aware when in direct boot mode if false, all
-     *                            packages are considered a match even if they are not aware.
-     * @return the target activity info of the intent it resolves to a specific package or
-     *         {@code null} if it resolved to the resolver activity
-     */
-    public static ActivityInfo getTargetActivityInfo(Context ctx, Intent intent,
-            int currentUserId, boolean onlyDirectBootAware) {
-        PackageManager packageManager = ctx.getPackageManager();
-        int flags = PackageManager.MATCH_DEFAULT_ONLY;
-        if (!onlyDirectBootAware) {
-            flags |=  PackageManager.MATCH_DIRECT_BOOT_AWARE
-                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-        }
-        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, flags, currentUserId);
-        if (appList.size() == 0) {
-            return null;
-        }
-        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
-                flags | PackageManager.GET_META_DATA, currentUserId);
-        if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
-            return null;
-        } else {
-            return resolved.activityInfo;
-        }
-    }
-
-    private static boolean wouldLaunchResolverActivity(
-            ResolveInfo resolved, List<ResolveInfo> appList) {
-        // If the list contains the above resolved activity, then it can't be
-        // ResolverActivity itself.
-        for (int i = 0; i < appList.size(); i++) {
-            ResolveInfo tmp = appList.get(i);
-            if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
-                    && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     private static class WidgetInfo {
         String contextPackage;
         int layoutId;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 63b6673..c9b550c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -35,6 +35,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -89,6 +90,8 @@
     private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener;
     @Mock
     private BubbleController.BubbleExpandListener mBubbleExpandListener;
+    @Mock
+    NotificationVisibility mNotificationVisibility;
 
     @Mock
     private PendingIntent mDeleteIntent;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
new file mode 100644
index 0000000..20af1ac
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import static org.mockito.AdditionalAnswers.answerVoid;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.dreams.IDreamManager;
+import android.service.notification.StatusBarNotification;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.ActivityIntentHelper;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
+
+    @Mock
+    private AssistManager mAssistManager;
+    @Mock
+    private NotificationEntryManager mEntryManager;
+    @Mock
+    private ActivityStarter mActivityStarter;
+    @Mock
+    private IStatusBarService mStatusBarService;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private NotificationRemoteInputManager mRemoteInputManager;
+    @Mock
+    private RemoteInputController mRemoteInputController;
+    @Mock
+    private ShadeController mShadeController;
+    @Mock
+    private KeyguardMonitor mKeyguardMonitor;
+    @Mock
+    private Handler mHandler;
+
+    @Mock
+    private ActivityIntentHelper mActivityIntentHelper;
+    @Mock
+    private PendingIntent mContentIntent;
+    @Mock
+    private NotificationData mNotificationData;
+    @Mock
+    private NotificationEntry mNotificationEntry;
+    @Mock
+    private NotificationEntry mBubbleEntry;
+
+    private NotificationActivityStarter mNotificationActivityStarter;
+
+    private NotificationTestHelper mNotificationTestHelper;
+    ExpandableNotificationRow mNotificationRow;
+
+    private final Answer<Void> mCallOnDismiss = answerVoid(
+            (ActivityStarter.OnDismissAction dismissAction, Runnable cancel,
+                    Boolean afterKeyguardGone) -> dismissAction.onDismiss());
+    private ArrayList<NotificationEntry> mActiveNotifications;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
+        when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
+
+        mActiveNotifications = new ArrayList<>();
+        mActiveNotifications.add(mNotificationEntry);
+        mActiveNotifications.add(mBubbleEntry);
+        when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
+        when(mNotificationEntry.getRow()).thenReturn(mNotificationRow);
+
+        mNotificationTestHelper = new NotificationTestHelper(mContext);
+        mNotificationRow = mNotificationTestHelper.createRow();
+
+        mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(),
+                mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class),
+                mock(NotificationPresenter.class), mEntryManager, mock(HeadsUpManagerPhone.class),
+                mActivityStarter, mock(ActivityLaunchAnimator.class), mStatusBarService,
+                mock(StatusBarStateController.class), mock(KeyguardManager.class),
+                mock(IDreamManager.class), mRemoteInputManager,
+                mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class),
+                mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardMonitor,
+                mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
+                mock(LockPatternUtils.class), mHandler, mActivityIntentHelper);
+
+
+        when(mContentIntent.isActivity()).thenReturn(true);
+        when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
+
+        // SBNActivityStarter expects contentIntent or fullScreenIntent to be set
+        mNotificationRow.getEntry().notification.getNotification().contentIntent = mContentIntent;
+
+        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+
+        // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
+        doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
+                any(ActivityStarter.OnDismissAction.class), any(), anyBoolean());
+
+        // set up addAfterKeyguardGoneRunnable to synchronously invoke the Runnable arg
+        doAnswer(answerVoid(Runnable::run))
+                .when(mShadeController).addAfterKeyguardGoneRunnable(any(Runnable.class));
+
+        // set up addPostCollapseAction to synchronously invoke the Runnable arg
+        doAnswer(answerVoid(Runnable::run))
+                .when(mShadeController).addPostCollapseAction(any(Runnable.class));
+
+        // set up Handler to synchronously invoke the Runnable arg
+        doAnswer(answerVoid(Runnable::run))
+                .when(mHandler).post(any(Runnable.class));
+    }
+
+    @Test
+    public void testOnNotificationClicked_whileKeyguardVisible()
+            throws PendingIntent.CanceledException, RemoteException {
+        // Given
+        when(mKeyguardMonitor.isShowing()).thenReturn(true);
+        when(mShadeController.isOccluded()).thenReturn(true);
+        when(mContentIntent.isActivity()).thenReturn(true);
+        when(mActivityIntentHelper.wouldShowOverLockscreen(any(Intent.class), anyInt()))
+                .thenReturn(false);
+        when(mActivityIntentHelper.wouldLaunchResolverActivity(any(Intent.class), anyInt()))
+                .thenReturn(false);
+
+        StatusBarNotification statusBarNotification = mNotificationRow.getEntry().notification;
+        statusBarNotification.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+
+        // When
+        mNotificationActivityStarter.onNotificationClicked(statusBarNotification,
+                mNotificationRow);
+
+        // Then
+        verify(mActivityStarter).dismissKeyguardThenExecute(
+                any(ActivityStarter.OnDismissAction.class),
+                any() /* cancel */,
+                anyBoolean() /* afterKeyguardGone */);
+
+        verify(mShadeController, atLeastOnce()).collapsePanel();
+
+        verify(mContentIntent).sendAndReturnResult(
+                any(Context.class),
+                anyInt() /* code */,
+                any() /* fillInIntent */,
+                any() /* PendingIntent.OnFinished */,
+                any() /* Handler */,
+                any() /* requiredPermission */,
+                any() /* Bundle options */);
+
+        verify(mAssistManager).hideAssist();
+
+        verify(mStatusBarService).onNotificationClick(
+                eq(mNotificationRow.getEntry().key), any(NotificationVisibility.class));
+
+        // Notification is removed due to FLAG_AUTO_CANCEL
+        verify(mEntryManager).performRemoveNotification(eq(statusBarNotification));
+    }
+}