Merge stage-aosp-master into pi-dev-plus-aosp
am: 8992652a8d

Change-Id: Ibbd1b67df89abe9531a2f4943b212293debdc2fb
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5d1a1b9..5b0bd6a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,6 +40,7 @@
             android:theme="@style/Theme.Settings.NoActionBar">
             <intent-filter priority="-1">
                 <action android:name="com.android.settings.action.SETTINGS_SEARCH" />
+                <action android:name="android.settings.APP_SEARCH_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
diff --git a/OWNERS b/OWNERS
index 7d9f541..1703318 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,8 +1,10 @@
-# People who can approve changes
-dhnishi@google.com
-juanlang@google.com
-mfritze@google.com
-zhfan@google.com
+## People who can approve changes
 
-# Emergency approvers in case the above are not available
-miket@google.com
\ No newline at end of file
+# Android auto
+rlagos@google.com
+
+# TV Settings
+leifhendrik@google.com
+
+# Mobile Settings
+zhfan@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
index d335b8c..0053f14 100644
--- a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
+++ b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
@@ -17,6 +17,7 @@
 package com.android.settings.intelligence.search.indexing;
 
 import static com.android.settings.intelligence.search.query.DatabaseResultTask.SELECT_COLUMNS;
+import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_AUTHORITY;
 import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_PACKAGE;
 import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
 import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_ENTRIES;
@@ -220,6 +221,7 @@
             values.put(DATA_ENTRIES, dataRow.entries);
             values.put(DATA_KEYWORDS, dataRow.spaceDelimitedKeywords);
             values.put(DATA_PACKAGE, dataRow.packageName);
+            values.put(DATA_AUTHORITY, dataRow.authority);
             values.put(CLASS_NAME, dataRow.className);
             values.put(SCREEN_TITLE, dataRow.screenTitle);
             values.put(INTENT_ACTION, dataRow.intentAction);
@@ -241,7 +243,7 @@
      * All rows which are disabled but no longer a non-indexable key will become enabled.
      *
      * @param database         The database to validate.
-     * @param nonIndexableKeys A map between package name and the set of non-indexable keys for it.
+     * @param nonIndexableKeys A map between authority and the set of non-indexable keys for it.
      */
     @VisibleForTesting
     void updateDataInDatabase(SQLiteDatabase database,
@@ -255,17 +257,17 @@
         final ContentValues enabledToDisabledValue = new ContentValues();
         enabledToDisabledValue.put(ENABLED, 0);
 
-        String packageName;
+        String authority;
         // TODO Refactor: Move these two loops into one method.
         while (enabledResults.moveToNext()) {
-            packageName = enabledResults.getString(enabledResults.getColumnIndexOrThrow(
-                    IndexDatabaseHelper.IndexColumns.DATA_PACKAGE));
+            authority = enabledResults.getString(enabledResults.getColumnIndexOrThrow(
+                    DATA_AUTHORITY));
             final String key = enabledResults.getString(enabledResults.getColumnIndexOrThrow(
-                    IndexDatabaseHelper.IndexColumns.DATA_KEY_REF));
-            final Set<String> packageKeys = nonIndexableKeys.get(packageName);
+                    DATA_KEY_REF));
+            final Set<String> authorityKeys = nonIndexableKeys.get(authority);
 
             // The indexed item is set to Enabled but is now non-indexable
-            if (packageKeys != null && packageKeys.contains(key)) {
+            if (authorityKeys != null && authorityKeys.contains(key)) {
                 final String whereClause = getKeyWhereClause(key);
                 database.update(TABLE_PREFS_INDEX, enabledToDisabledValue, whereClause, null);
             }
@@ -279,17 +281,17 @@
         disabledToEnabledValue.put(ENABLED, 1);
 
         while (disabledResults.moveToNext()) {
-            packageName = disabledResults.getString(disabledResults.getColumnIndexOrThrow(
-                    IndexDatabaseHelper.IndexColumns.DATA_PACKAGE));
+            authority = disabledResults.getString(disabledResults.getColumnIndexOrThrow(
+                    DATA_AUTHORITY));
 
             final String key = disabledResults.getString(disabledResults.getColumnIndexOrThrow(
-                    IndexDatabaseHelper.IndexColumns.DATA_KEY_REF));
-            final Set<String> packageKeys = nonIndexableKeys.get(packageName);
+                    DATA_KEY_REF));
+            final Set<String> authorityKeys = nonIndexableKeys.get(authority);
 
             // The indexed item is set to Disabled but is no longer non-indexable.
-            // We do not enable keys when packageKeys is null because it means the keys came
-            // from an unrecognized package and therefore should not be surfaced as results.
-            if (packageKeys != null && !packageKeys.contains(key)) {
+            // We do not enable keys when authorityKeys is null because it means the keys came
+            // from an unrecognized authority and therefore should not be surfaced as results.
+            if (authorityKeys != null && !authorityKeys.contains(key)) {
                 final String whereClause = getKeyWhereClause(key);
                 database.update(TABLE_PREFS_INDEX, disabledToEnabledValue, whereClause, null);
             }
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexData.java b/src/com/android/settings/intelligence/search/indexing/IndexData.java
index d178344..904deaf 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexData.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexData.java
@@ -38,6 +38,7 @@
      * @see SearchIndexableData#iconResId
      */
     public final String packageName;
+    public final String authority;
     public final String locale;
     public final String updatedTitle;
     public final String normalizedTitle;
@@ -87,6 +88,7 @@
         spaceDelimitedKeywords = normalizeKeywords(builder.mKeywords);
         intentAction = builder.mIntentAction;
         packageName = builder.mPackageName;
+        authority = builder.mAuthority;
         intentTargetPackage = builder.mIntentTargetPackage;
         intentTargetClass = builder.mIntentTargetClass;
         enabled = builder.mEnabled;
@@ -155,6 +157,7 @@
         private String mChildClassName;
         private String mScreenTitle;
         private String mPackageName;
+        private String mAuthority;
         private int mIconResId;
         private String mKeywords;
         private String mIntentAction;
@@ -213,6 +216,11 @@
             return this;
         }
 
+        public Builder setAuthority(String authority) {
+            mAuthority = authority;
+            return this;
+        }
+
         public Builder setIconResId(int iconResId) {
             mIconResId = iconResId;
             return this;
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java b/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
index f2e133a..bd53596 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
@@ -20,11 +20,11 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
-import android.os.AsyncTask;
 import android.provider.SearchIndexableData;
 import android.provider.SearchIndexableResource;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
+import androidx.collection.ArraySet;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -42,7 +42,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -74,25 +73,32 @@
      */
     public List<IndexData> convertPreIndexDataToIndexData(PreIndexData preIndexData) {
         final long startConversion = System.currentTimeMillis();
-        final List<SearchIndexableData> indexableData = preIndexData.getDataToUpdate();
+        final Map<String, List<SearchIndexableData>> indexableDataMap =
+                preIndexData.getDataToUpdate();
         final Map<String, Set<String>> nonIndexableKeys = preIndexData.getNonIndexableKeys();
         final List<IndexData> indexData = new ArrayList<>();
 
-        for (SearchIndexableData data : indexableData) {
-            if (data instanceof SearchIndexableRaw) {
-                final SearchIndexableRaw rawData = (SearchIndexableRaw) data;
-                final Set<String> rawNonIndexableKeys = nonIndexableKeys.get(
-                        rawData.intentTargetPackage);
-                final IndexData convertedRaw = convertRaw(mContext, rawData, rawNonIndexableKeys);
-                if (convertedRaw != null) {
-                    indexData.add(convertedRaw);
+        for (Map.Entry<String, List<SearchIndexableData>> entry : indexableDataMap.entrySet()) {
+            final String authority = entry.getKey();
+            final List<SearchIndexableData> indexableData = entry.getValue();
+
+            for (SearchIndexableData data : indexableData) {
+                if (data instanceof SearchIndexableRaw) {
+                    final SearchIndexableRaw rawData = (SearchIndexableRaw) data;
+                    final Set<String> rawNonIndexableKeys = nonIndexableKeys.get(authority);
+                    final IndexData convertedRaw = convertRaw(mContext, authority, rawData,
+                            rawNonIndexableKeys);
+                    if (convertedRaw != null) {
+                        indexData.add(convertedRaw);
+                    }
+                } else if (data instanceof SearchIndexableResource) {
+                    final SearchIndexableResource sir = (SearchIndexableResource) data;
+                    final Set<String> resourceNonIndexableKeys =
+                            getNonIndexableKeysForResource(nonIndexableKeys, authority);
+                    final List<IndexData> resourceData = convertResource(sir, authority,
+                            resourceNonIndexableKeys);
+                    indexData.addAll(resourceData);
                 }
-            } else if (data instanceof SearchIndexableResource) {
-                final SearchIndexableResource sir = (SearchIndexableResource) data;
-                final Set<String> resourceNonIndexableKeys =
-                        getNonIndexableKeysForResource(nonIndexableKeys, sir.packageName);
-                final List<IndexData> resourceData = convertResource(sir, resourceNonIndexableKeys);
-                indexData.addAll(resourceData);
             }
         }
 
@@ -150,10 +156,10 @@
      * and there is some data sanitization in the conversion.
      */
     @Nullable
-    private IndexData convertRaw(Context context, SearchIndexableRaw raw,
+    private IndexData convertRaw(Context context, String authority, SearchIndexableRaw raw,
             Set<String> nonIndexableKeys) {
         if (TextUtils.isEmpty(raw.key)) {
-            Log.w(TAG, "Skipping null key for raw indexable " + raw.packageName + "/" + raw.title);
+            Log.w(TAG, "Skipping null key for raw indexable " + authority + "/" + raw.title);
             return null;
         }
         // A row is enabled if it does not show up as an nonIndexableKey
@@ -172,6 +178,7 @@
                 .setIntentTargetClass(raw.intentTargetClass)
                 .setEnabled(enabled)
                 .setPackageName(raw.packageName)
+                .setAuthority(authority)
                 .setKey(raw.key);
 
         return builder.build(context);
@@ -184,7 +191,7 @@
      *
      * TODO (b/33577327) simplify this method.
      */
-    private List<IndexData> convertResource(SearchIndexableResource sir,
+    private List<IndexData> convertResource(SearchIndexableResource sir, String authority,
             Set<String> nonIndexableKeys) {
         final Context context = sir.context;
         XmlResourceParser parser = null;
@@ -244,6 +251,7 @@
                     .setKeywords(headerKeywords)
                     .setClassName(sir.className)
                     .setPackageName(sir.packageName)
+                    .setAuthority(authority)
                     .setIntentAction(sir.intentAction)
                     .setIntentTargetPackage(sir.intentTargetPackage)
                     .setIntentTargetClass(sir.intentTargetClass)
@@ -285,6 +293,7 @@
                         .setScreenTitle(screenTitle)
                         .setIconResId(iconResId)
                         .setPackageName(sir.packageName)
+                        .setAuthority(authority)
                         .setIntentAction(sir.intentAction)
                         .setIntentTargetPackage(sir.intentTargetPackage)
                         .setIntentTargetClass(sir.intentTargetClass)
@@ -352,9 +361,8 @@
     }
 
     private Set<String> getNonIndexableKeysForResource(Map<String, Set<String>> nonIndexableKeys,
-            String packageName) {
-        return nonIndexableKeys.containsKey(packageName)
-                ? nonIndexableKeys.get(packageName)
-                : new HashSet<String>();
+            String authority) {
+        final Set<String> result = nonIndexableKeys.get(authority);
+        return result != null ? result : new ArraySet<>();
     }
 }
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java b/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
index 51cc221..cc90d21 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
@@ -37,7 +37,7 @@
     private static final String TAG = "IndexDatabaseHelper";
 
     private static final String DATABASE_NAME = "search_index.db";
-    private static final int DATABASE_VERSION = 119;
+    private static final int DATABASE_VERSION = 120;
 
     @VisibleForTesting
     static final String SHARED_PREFS_TAG = "indexing_manager";
@@ -61,6 +61,7 @@
         String DATA_ENTRIES = "data_entries";
         String DATA_KEYWORDS = "data_keywords";
         String DATA_PACKAGE = "package";
+        String DATA_AUTHORITY = "authority";
         String CLASS_NAME = "class_name";
         String SCREEN_TITLE = "screen_title";
         String INTENT_ACTION = "intent_action";
@@ -111,6 +112,8 @@
                     ", " +
                     IndexColumns.DATA_PACKAGE +
                     ", " +
+                    IndexColumns.DATA_AUTHORITY +
+                    ", " +
                     IndexColumns.SCREEN_TITLE +
                     ", " +
                     IndexColumns.CLASS_NAME +
diff --git a/src/com/android/settings/intelligence/search/indexing/PreIndexData.java b/src/com/android/settings/intelligence/search/indexing/PreIndexData.java
index 8f8ce07..7ea03fd 100644
--- a/src/com/android/settings/intelligence/search/indexing/PreIndexData.java
+++ b/src/com/android/settings/intelligence/search/indexing/PreIndexData.java
@@ -32,12 +32,12 @@
  */
 public class PreIndexData {
 
-    private final List<SearchIndexableData> mDataToUpdate;
+    private final Map<String, List<SearchIndexableData>> mDataToUpdate;
     private final Map<String, Set<String>> mNonIndexableKeys;
     private final List<Pair<String, String>> mSiteMapPairs;
 
     public PreIndexData() {
-        mDataToUpdate = new ArrayList<>();
+        mDataToUpdate = new HashMap<>();
         mNonIndexableKeys = new HashMap<>();
         mSiteMapPairs = new ArrayList<>();
     }
@@ -46,7 +46,7 @@
         return mNonIndexableKeys;
     }
 
-    public List<SearchIndexableData> getDataToUpdate() {
+    public Map<String, List<SearchIndexableData>> getDataToUpdate() {
         return mDataToUpdate;
     }
 
@@ -58,8 +58,17 @@
         mNonIndexableKeys.put(authority, keys);
     }
 
-    public void addDataToUpdate(List<? extends SearchIndexableData> data) {
-        mDataToUpdate.addAll(data);
+    public void addDataToUpdate(String authority, List<? extends SearchIndexableData> data) {
+        if (data.isEmpty()) {
+            return;
+        }
+
+        List<SearchIndexableData> indexableData = mDataToUpdate.get(authority);
+        if (indexableData == null) {
+            mDataToUpdate.put(authority, new ArrayList<>(data));
+        } else {
+            indexableData.addAll(data);
+        }
     }
 
     public void addSiteMapPairs(List<Pair<String, String>> siteMapPairs) {
diff --git a/src/com/android/settings/intelligence/search/indexing/PreIndexDataCollector.java b/src/com/android/settings/intelligence/search/indexing/PreIndexDataCollector.java
index 1dbc9e1..a859113 100644
--- a/src/com/android/settings/intelligence/search/indexing/PreIndexDataCollector.java
+++ b/src/com/android/settings/intelligence/search/indexing/PreIndexDataCollector.java
@@ -111,12 +111,14 @@
             final Context context = mContext.createPackageContext(packageName, 0);
 
             final Uri uriForResources = buildUriForXmlResources(authority);
-            mIndexData.addDataToUpdate(getIndexablesForXmlResourceUri(context, packageName,
-                    uriForResources, SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS));
+            mIndexData.addDataToUpdate(authority, getIndexablesForXmlResourceUri(
+                    context, packageName, uriForResources,
+                    SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS));
 
             final Uri uriForRawData = buildUriForRawData(authority);
-            mIndexData.addDataToUpdate(getIndexablesForRawDataUri(context, packageName,
-                    uriForRawData, SearchIndexablesContract.INDEXABLES_RAW_COLUMNS));
+            mIndexData.addDataToUpdate(authority, getIndexablesForRawDataUri(
+                    context, packageName, uriForRawData,
+                    SearchIndexablesContract.INDEXABLES_RAW_COLUMNS));
 
             final Uri uriForSiteMap = buildUriForSiteMap(authority);
             mIndexData.addSiteMapPairs(getSiteMapFromProvider(context, uriForSiteMap));
diff --git a/src/com/android/settings/intelligence/search/query/DatabaseResultTask.java b/src/com/android/settings/intelligence/search/query/DatabaseResultTask.java
index 93bc261..07f9863 100644
--- a/src/com/android/settings/intelligence/search/query/DatabaseResultTask.java
+++ b/src/com/android/settings/intelligence/search/query/DatabaseResultTask.java
@@ -63,6 +63,7 @@
             IndexColumns.ICON,
             IndexColumns.INTENT_ACTION,
             IndexColumns.DATA_PACKAGE,
+            IndexColumns.DATA_AUTHORITY,
             IndexColumns.INTENT_TARGET_PACKAGE,
             IndexColumns.INTENT_TARGET_CLASS,
             IndexColumns.DATA_KEY_REF,
diff --git a/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java b/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
index c387e9d..2502e2a 100644
--- a/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
+++ b/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
@@ -182,14 +182,17 @@
                 // First get override data
                 final Bundle overrideData = getOverrideData(metaData);
                 // Get icon
-                if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
-                    iconRes = metaData.getInt(META_DATA_PREFERENCE_ICON);
-                } else {
-                    iconRes = mResolveInfo.activityInfo.icon;
-                }
-                if (iconRes != 0) {
-                    icon = Icon.createWithResource(
-                            mResolveInfo.activityInfo.packageName, iconRes);
+                icon = getIconFromBundle(overrideData, META_DATA_PREFERENCE_ICON);
+                if (icon == null) {
+                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
+                        iconRes = metaData.getInt(META_DATA_PREFERENCE_ICON);
+                    } else {
+                        iconRes = mResolveInfo.activityInfo.icon;
+                    }
+                    if (iconRes != 0) {
+                        icon = Icon.createWithResource(
+                                mResolveInfo.activityInfo.packageName, iconRes);
+                    }
                 }
                 // Get title
                 title = getStringFromBundle(overrideData, META_DATA_PREFERENCE_TITLE);
@@ -241,6 +244,14 @@
         return bundle.getString(key);
     }
 
+    /** Extracts an Icon object from bundle. */
+    private Icon getIconFromBundle(Bundle bundle, String key) {
+        if (bundle == null || TextUtils.isEmpty(key)) {
+            return null;
+        }
+        return bundle.getParcelable(key);
+    }
+
     private Bundle getOverrideData(Bundle metadata) {
         if (metadata == null || !metadata.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
             Log.d(TAG, "Metadata null or has no info about summary_uri");