Merge "Fix installed app search query."
diff --git a/src/com/android/settings/search2/InstalledAppResultLoader.java b/src/com/android/settings/search2/InstalledAppResultLoader.java
index 449e52c..14735bd 100644
--- a/src/com/android/settings/search2/InstalledAppResultLoader.java
+++ b/src/com/android/settings/search2/InstalledAppResultLoader.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.net.Uri;
 import android.os.UserHandle;
@@ -41,11 +42,14 @@
 
     private static final int NAME_NO_MATCH = -1;
     private static final int NAME_EXACT_MATCH = 0;
+    private static final Intent LAUNCHER_PROBE = new Intent(Intent.ACTION_MAIN)
+            .addCategory(Intent.CATEGORY_LAUNCHER);
 
     private final String mQuery;
     private final UserManager mUserManager;
     private final PackageManagerWrapper mPackageManager;
 
+
     public InstalledAppResultLoader(Context context, PackageManagerWrapper pmWrapper,
             String query) {
         super(context);
@@ -67,7 +71,7 @@
                                     | (user.isAdmin() ? PackageManager.MATCH_ANY_USER : 0),
                             user.id);
             for (ApplicationInfo info : apps) {
-                if (info.isSystemApp()) {
+                if (!shouldIncludeAsCandidate(info, user)) {
                     continue;
                 }
                 final CharSequence label = info.loadLabel(pm);
@@ -91,6 +95,22 @@
         return results;
     }
 
+    private boolean shouldIncludeAsCandidate(ApplicationInfo info, UserInfo user) {
+        if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
+                || (info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+            return true;
+        }
+        final Intent launchIntent = new Intent(LAUNCHER_PROBE)
+                .setPackage(info.packageName);
+        final List<ResolveInfo> intents = mPackageManager.queryIntentActivitiesAsUser(
+                launchIntent,
+                PackageManager.MATCH_DISABLED_COMPONENTS
+                        | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                user.id);
+        return intents != null && intents.size() != 0;
+    }
+
     @Override
     protected void onDiscardResult(List<SearchResult> result) {
 
diff --git a/tests/robotests/src/com/android/settings/search2/InstalledAppResultLoaderTest.java b/tests/robotests/src/com/android/settings/search2/InstalledAppResultLoaderTest.java
index 8fde73d..4f62a9e 100644
--- a/tests/robotests/src/com/android/settings/search2/InstalledAppResultLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/search2/InstalledAppResultLoaderTest.java
@@ -17,6 +17,8 @@
 package com.android.settings.search2;
 
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.os.UserManager;
 
@@ -38,8 +40,11 @@
 import java.util.List;
 
 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @RunWith(SettingsRobolectricTestRunner.class)
@@ -95,6 +100,55 @@
     }
 
     @Test
+    public void query_matchingQuery_shouldReturnSystemAppUpdates() {
+        when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt()))
+                .thenReturn(Arrays.asList(
+                        ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_UPDATED_SYSTEM_APP,
+                                0 /* targetSdkVersion */)));
+        final String query = "app";
+
+        mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
+
+        assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
+    }
+
+    @Test
+    public void query_matchingQuery_shouldReturnSystemAppIfLaunchable() {
+        when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt()))
+                .thenReturn(Arrays.asList(
+                        ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_SYSTEM,
+                                0 /* targetSdkVersion */)));
+        final List<ResolveInfo> list = mock(List.class);
+        when(list.size()).thenReturn(1);
+        when(mPackageManagerWrapper.queryIntentActivitiesAsUser(
+                any(Intent.class), anyInt(), anyInt()))
+                .thenReturn(list);
+
+        final String query = "app";
+
+        mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
+
+        assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
+    }
+
+    @Test
+    public void query_matchingQuery_shouldNOtReturnSystemAppIfNotLaunchable() {
+        when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), anyInt()))
+                .thenReturn(Arrays.asList(
+                        ApplicationTestUtils.buildInfo(0 /* uid */, "app1", FLAG_SYSTEM,
+                                0 /* targetSdkVersion */)));
+        when(mPackageManagerWrapper.queryIntentActivitiesAsUser(
+                any(Intent.class), anyInt(), anyInt()))
+                .thenReturn(null);
+
+        final String query = "app";
+
+        mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
+
+        assertThat(mLoader.loadInBackground()).isEmpty();
+    }
+
+    @Test
     public void query_matchingQuery_shouldRankBasedOnSimilarity() {
         final String query = "app";