[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: b223baae6d -s ours
am skip reason: subject contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/SettingsIntelligence/+/22913527
Change-Id: I4592e78125bf992a162c6a87554161c2141c7182
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index d019e75..40a799d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -33,6 +33,7 @@
"androidx.preference_preference",
"androidx.recyclerview_recyclerview",
"androidx.legacy_legacy-preference-v14",
+ "SettingsLibActivityEmbedding",
],
proto: {
type: "nano",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d776e59..4d49922 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -49,7 +49,8 @@
<activity
android:name=".search.SearchActivity"
android:exported="true"
- android:theme="@style/Theme.Settings.NoActionBar">
+ android:theme="@style/Theme.Settings.NoActionBar"
+ android:windowSoftInputMode="adjustResize">
<intent-filter priority="-1">
<action android:name="com.android.settings.action.SETTINGS_SEARCH" />
<action android:name="android.settings.APP_SEARCH_SETTINGS" />
diff --git a/OWNERS b/OWNERS
index 3c22c9a..14bb338 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,8 +4,6 @@
rlagos@google.com # OWNER for SUW related code
alexstetson@google.com # OWNER for Car Settings related code
-# TV Settings
-leifhendrik@google.com
-
# Mobile Settings
-tmfang@google.com
+stanleytfwang@google.com
+chiujason@google.com
diff --git a/res/drawable/search_bar_selected_background.xml b/res/drawable/search_bar_selected_background.xml
new file mode 100644
index 0000000..494302a
--- /dev/null
+++ b/res/drawable/search_bar_selected_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <item android:drawable="@color/search_bar_background"/>
+</ripple>
diff --git a/res/layout/search_panel.xml b/res/layout/search_panel.xml
index 5f621cd..990d11a 100644
--- a/res/layout/search_panel.xml
+++ b/res/layout/search_panel.xml
@@ -25,7 +25,6 @@
android:id="@+id/search_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@color/search_panel_background"
android:elevation="4dp">
<androidx.cardview.widget.CardView
android:id="@+id/search_bar"
@@ -33,7 +32,6 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/search_bar_margin"
app:cardCornerRadius="2dp"
- app:cardBackgroundColor="?android:attr/colorBackground"
app:cardElevation="2dp">
<Toolbar
android:id="@+id/search_toolbar"
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
new file mode 100644
index 0000000..3be2c99
--- /dev/null
+++ b/res/values-night/colors.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<resources
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+
+ <color name="search_bar_background">?androidprv:attr/colorSurfaceVariant</color>
+
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a2105f0..5c3b05c 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -18,5 +18,5 @@
<resources>
<color name="launcher_background_color">#ff008577</color>
- <color name="search_panel_background">#f2f2f2</color>
+ <color name="search_bar_background">?android:attr/colorBackground</color>
</resources>
diff --git a/src/com/android/settings/intelligence/search/IntentSearchViewHolder.java b/src/com/android/settings/intelligence/search/IntentSearchViewHolder.java
index b643368..ee574aa 100644
--- a/src/com/android/settings/intelligence/search/IntentSearchViewHolder.java
+++ b/src/com/android/settings/intelligence/search/IntentSearchViewHolder.java
@@ -16,13 +16,16 @@
*/
package com.android.settings.intelligence.search;
+import static com.android.settings.intelligence.search.indexing.DatabaseIndexingUtils.SEARCH_RESULT_TRAMPOLINE_ACTION;
+
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import androidx.annotation.VisibleForTesting;
import android.util.Log;
import android.view.View;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.intelligence.nano.SettingsIntelligenceLogProto;
import java.util.List;
@@ -59,8 +62,11 @@
final Intent intent = result.payload.getIntent();
// Use app user id to support work profile use case.
if (result instanceof AppSearchResult) {
- AppSearchResult appResult = (AppSearchResult) result;
- fragment.getActivity().startActivity(intent);
+ if (SEARCH_RESULT_TRAMPOLINE_ACTION.equals(intent.getAction())) {
+ fragment.startActivityForResult(intent, REQUEST_CODE_NO_OP);
+ } else {
+ fragment.startActivity(intent);
+ }
} else {
final PackageManager pm = fragment.getActivity().getPackageManager();
final List<ResolveInfo> info = pm.queryIntentActivities(intent, 0 /* flags */);
diff --git a/src/com/android/settings/intelligence/search/SearchFragment.java b/src/com/android/settings/intelligence/search/SearchFragment.java
index c76eda3..86b5b37 100644
--- a/src/com/android/settings/intelligence/search/SearchFragment.java
+++ b/src/com/android/settings/intelligence/search/SearchFragment.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.VisibleForTesting;
+import androidx.cardview.widget.CardView;
import androidx.loader.content.Loader;
import androidx.loader.app.LoaderManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -149,6 +150,9 @@
mNoResultsView = view.findViewById(R.id.no_results_layout);
+ final CardView cardView = view.findViewById(R.id.search_bar);
+ cardView.setBackgroundResource(R.drawable.search_bar_selected_background);
+
final Toolbar toolbar = view.findViewById(R.id.search_toolbar);
activity.setActionBar(toolbar);
activity.getActionBar().setDisplayHomeAsUpEnabled(true);
@@ -289,6 +293,7 @@
}
public void onSearchResultClicked(SearchViewHolder resultViewHolder, SearchResult result) {
+ hideKeyboard();
logSearchResultClicked(resultViewHolder, result);
mSearchFeatureProvider.searchResultClicked(getContext(), mQuery, result);
mSavedQueryController.saveQuery(mQuery);
diff --git a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
index 32add54..146b730 100644
--- a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
+++ b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingManager.java
@@ -16,13 +16,13 @@
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.SearchFeatureProvider.DEBUG;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
+import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_AUTHORITY;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_ENTRIES;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_KEY_REF;
+import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_PACKAGE;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.DATA_TITLE;
@@ -35,8 +35,9 @@
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.PAYLOAD;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.SCREEN_TITLE;
+import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.IndexColumns.TOP_LEVEL_MENU_KEY;
import static com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
-import static com.android.settings.intelligence.search.SearchFeatureProvider.DEBUG;
+import static com.android.settings.intelligence.search.query.DatabaseResultTask.SELECT_COLUMNS;
import android.content.ContentValues;
import android.content.Context;
@@ -47,13 +48,15 @@
import android.database.sqlite.SQLiteException;
import android.os.AsyncTask;
import android.provider.SearchIndexablesContract;
-import androidx.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.intelligence.nano.SettingsIntelligenceLogProto;
import com.android.settings.intelligence.overlay.FeatureFactory;
+import com.android.settings.intelligence.search.sitemap.HighlightableMenu;
import com.android.settings.intelligence.search.sitemap.SiteMapPair;
import java.util.List;
@@ -160,9 +163,21 @@
database.beginTransaction();
// Convert all Pre-index data to Index data and and insert to db.
- final List<IndexData> indexData = getIndexData(preIndexData);
- insertIndexData(database, indexData);
+ List<IndexData> indexData = getIndexData(preIndexData);
+
+ // Load SiteMap before writing index data into DB for updating payload
insertSiteMapData(database, getSiteMapPairs(indexData, preIndexData.getSiteMapPairs()));
+ // Flag to re-init site map data in SiteMapManager.
+ FeatureFactory.get(mContext).searchFeatureProvider()
+ .getSiteMapManager()
+ .setInitialized(false);
+
+ // Update payload based on the site map to find the top menu entry
+ if (HighlightableMenu.isFeatureEnabled(mContext)) {
+ indexData = updateIndexDataPayload(mContext, indexData);
+ }
+
+ insertIndexData(database, indexData);
// Only check for non-indexable key updates after initial index.
// Enabled state with non-indexable keys is checked when items are first inserted.
@@ -178,7 +193,7 @@
private List<IndexData> getIndexData(PreIndexData data) {
if (mConverter == null) {
- mConverter = getIndexDataConverter(mContext);
+ mConverter = getIndexDataConverter();
}
return mConverter.convertPreIndexDataToIndexData(data);
}
@@ -186,7 +201,7 @@
private List<SiteMapPair> getSiteMapPairs(List<IndexData> indexData,
List<Pair<String, String>> siteMapClassNames) {
if (mConverter == null) {
- mConverter = getIndexDataConverter(mContext);
+ mConverter = getIndexDataConverter();
}
return mConverter.convertSiteMapPairs(indexData, siteMapClassNames);
}
@@ -201,6 +216,13 @@
}
}
+ private List<IndexData> updateIndexDataPayload(Context context, List<IndexData> indexData) {
+ if (mConverter == null) {
+ mConverter = getIndexDataConverter();
+ }
+ return mConverter.updateIndexDataPayload(context, indexData);
+ }
+
/**
* Inserts all of the entries in {@param indexData} into the {@param database}
* as Search Data and as part of the Information Hierarchy.
@@ -232,6 +254,7 @@
values.put(DATA_KEY_REF, dataRow.key);
values.put(PAYLOAD_TYPE, dataRow.payloadType);
values.put(PAYLOAD, dataRow.payload);
+ values.put(TOP_LEVEL_MENU_KEY, dataRow.topLevelMenuKey);
database.replaceOrThrow(TABLE_PREFS_INDEX, null, values);
}
@@ -316,8 +339,13 @@
* Protected method to get a new IndexDataConverter instance. This method can be overridden
* in subclasses to substitute in a custom IndexDataConverter.
*/
+ protected IndexDataConverter getIndexDataConverter() {
+ return new IndexDataConverter();
+ }
+
+ @Deprecated
protected IndexDataConverter getIndexDataConverter(Context context) {
- return new IndexDataConverter(context);
+ return getIndexDataConverter();
}
public class IndexingTask extends AsyncTask<Void, Void, Void> {
@@ -355,4 +383,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingUtils.java b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingUtils.java
index 534a20c..c7afcd4 100644
--- a/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingUtils.java
+++ b/src/com/android/settings/intelligence/search/indexing/DatabaseIndexingUtils.java
@@ -16,9 +16,13 @@
package com.android.settings.intelligence.search.indexing;
+import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY;
+import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.text.TextUtils;
/**
@@ -44,16 +48,51 @@
public static final String SEARCH_RESULT_TRAMPOLINE_ACTION =
"com.android.settings.SEARCH_RESULT_TRAMPOLINE";
+ // Additional extra of Settings#ACTION_SETTINGS_LARGE_SCREEN_DEEP_LINK.
+ // Set & get Uri of the Intent separately to prevent failure of Intent#ParseUri.
+ private static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA =
+ "settings_large_screen_deep_link_intent_data";
+
/**
* Builds intent that launches the search destination as a sub-setting.
*/
- public static Intent buildSearchTrampolineIntent(Context context, String className, String key,
- String screenTitle) {
+ public static Intent buildSearchTrampolineIntent(String className, String key,
+ String screenTitle, String highlightMenuKey) {
final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION);
intent.putExtra(EXTRA_SHOW_FRAGMENT, className)
.putExtra(EXTRA_SHOW_FRAGMENT_TITLE, screenTitle)
.putExtra(EXTRA_SOURCE_METRICS_CATEGORY, DASHBOARD_SEARCH_RESULTS)
- .putExtra(EXTRA_FRAGMENT_ARG_KEY, key);
+ .putExtra(EXTRA_FRAGMENT_ARG_KEY, key)
+ .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey);
+ return intent;
+ }
+
+ /**
+ * Builds intent that launches the search destination as a deep link.
+ */
+ public static Intent buildSearchTrampolineIntent(String action, String targetPackage,
+ String targetClass, String key, String highlightMenuKey) {
+ final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION);
+ intent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI,
+ buildDirectSearchResultIntent(action, targetPackage, targetClass, key)
+ .toUri(Intent.URI_INTENT_SCHEME))
+ .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey);
+ return intent;
+ }
+
+ /**
+ * Builds intent that launches the search destination as a deep link.
+ */
+ public static Intent buildSearchTrampolineIntent(Intent targetIntent, String highlightMenuKey) {
+ // Relay target intent data to prevent future failure of Intent#ParseUri.
+ final Uri data = targetIntent.getData();
+ targetIntent = new Intent(targetIntent);
+ targetIntent.setData(null);
+ final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION);
+ intent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI,
+ targetIntent.toUri(Intent.URI_INTENT_SCHEME))
+ .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey)
+ .putExtra(EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, data);
return intent;
}
@@ -64,6 +103,7 @@
final ComponentName component = new ComponentName(targetPackage, targetClass);
intent.setComponent(component);
}
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexData.java b/src/com/android/settings/intelligence/search/indexing/IndexData.java
index 7318eaa..75de062 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexData.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexData.java
@@ -57,7 +57,10 @@
public final String key;
public final int payloadType;
public final byte[] payload;
+ public final String highlightableMenuKey; // the key of top level settings row
+ public final String topLevelMenuKey; // the key for highlighting the menu entry
+ private final Builder mBuilder;
private static final String NON_BREAKING_HYPHEN = "\u2011";
private static final String EMPTY = "";
private static final String HYPHEN = "-";
@@ -96,6 +99,14 @@
payloadType = builder.mPayloadType;
payload = builder.mPayload != null ? ResultPayloadUtils.marshall(builder.mPayload)
: null;
+ highlightableMenuKey = builder.mHighlightableMenuKey;
+ topLevelMenuKey = builder.mTopLevelMenuKey;
+ mBuilder = builder;
+ }
+
+ /** Returns the builder of the IndexData. */
+ public Builder mutate() {
+ return mBuilder;
}
@Override
@@ -168,6 +179,8 @@
@ResultPayload.PayloadType
private int mPayloadType;
private ResultPayload mPayload;
+ private String mHighlightableMenuKey;
+ private String mTopLevelMenuKey;
@Override
public String toString() {
@@ -277,6 +290,17 @@
return this;
}
+ public Builder setHighlightableMenuKey(String highlightableMenuKey) {
+ mHighlightableMenuKey = highlightableMenuKey;
+ return this;
+ }
+
+ Builder setTopLevelMenuKey(String topLevelMenuKey) {
+ mTopLevelMenuKey = topLevelMenuKey;
+ mPayload = null; // clear the payload to rebuild intent
+ return this;
+ }
+
/**
* Payload type is added when a Payload is added to the Builder in {setPayload}
*
@@ -292,11 +316,11 @@
* Adds intent to inline payloads, or creates an Intent Payload as a fallback if the
* payload is null.
*/
- private void setIntent(Context context) {
+ private void setIntent() {
if (mPayload != null) {
return;
}
- final Intent intent = buildIntent(context);
+ final Intent intent = buildIntent();
mPayload = new ResultPayload(intent);
mPayloadType = ResultPayload.PayloadType.INTENT;
}
@@ -305,25 +329,35 @@
* Builds Intent payload for the builder.
* This protected method that can be overridden in a subclass for custom intents.
*/
- protected Intent buildIntent(Context context) {
+ protected Intent buildIntent() {
final Intent intent;
// TODO REFACTOR (b/62807132) With inline results re-add proper intent support
boolean isEmptyIntentAction = TextUtils.isEmpty(mIntentAction);
if (isEmptyIntentAction) {
// No intent action is set, or the intent action is for a sub-setting.
- intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(context, mClassName,
- mKey, mScreenTitle);
+ intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(mClassName, mKey,
+ mScreenTitle, mTopLevelMenuKey);
} else {
- intent = DatabaseIndexingUtils.buildDirectSearchResultIntent(mIntentAction,
- mIntentTargetPackage, mIntentTargetClass, mKey);
+ if (!TextUtils.isEmpty(mTopLevelMenuKey)) {
+ intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(mIntentAction,
+ mIntentTargetPackage, mIntentTargetClass, mKey, mTopLevelMenuKey);
+ } else {
+ intent = DatabaseIndexingUtils.buildDirectSearchResultIntent(mIntentAction,
+ mIntentTargetPackage, mIntentTargetClass, mKey);
+ }
}
return intent;
}
- public IndexData build(Context context) {
- setIntent(context);
+ @Deprecated
+ protected Intent buildIntent(Context context) {
+ return buildIntent();
+ }
+
+ public IndexData build() {
+ setIntent();
return new IndexData(this);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java b/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
index f57ce6b..670bb70 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexDataConverter.java
@@ -34,6 +34,8 @@
import com.android.settings.intelligence.search.ResultPayload;
import com.android.settings.intelligence.search.SearchFeatureProvider;
import com.android.settings.intelligence.search.SearchIndexableRaw;
+import com.android.settings.intelligence.search.sitemap.HighlightableMenu;
+import com.android.settings.intelligence.search.sitemap.SiteMapManager;
import com.android.settings.intelligence.search.sitemap.SiteMapPair;
import org.xmlpull.v1.XmlPullParser;
@@ -54,15 +56,17 @@
private static final String TAG = "IndexDataConverter";
+ private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen";
private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference";
private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference";
private static final List<String> SKIP_NODES = Arrays.asList("intent", "extra");
- private final Context mContext;
+ public IndexDataConverter() {
+ }
+ @Deprecated
public IndexDataConverter(Context context) {
- mContext = context;
}
/**
@@ -86,7 +90,7 @@
if (data instanceof SearchIndexableRaw) {
final SearchIndexableRaw rawData = (SearchIndexableRaw) data;
final Set<String> rawNonIndexableKeys = nonIndexableKeys.get(authority);
- final IndexData convertedRaw = convertRaw(mContext, authority, rawData,
+ final IndexData convertedRaw = convertRaw(authority, rawData,
rawNonIndexableKeys);
if (convertedRaw != null) {
indexData.add(convertedRaw);
@@ -130,7 +134,7 @@
classToTitleMap.put(row.className, row.screenTitle);
if (!TextUtils.isEmpty(row.childClassName)) {
pairs.add(new SiteMapPair(row.className, row.screenTitle,
- row.childClassName, row.updatedTitle));
+ row.childClassName, row.updatedTitle, row.highlightableMenuKey));
}
}
// Step 2: Extend the sitemap pairs by adding dynamic pairs provided by
@@ -143,20 +147,41 @@
Log.w(TAG, "Cannot build sitemap pair for incomplete names "
+ pair + parentName + childName);
} else {
- pairs.add(new SiteMapPair(pair.first, parentName, pair.second, childName));
+ pairs.add(new SiteMapPair(pair.first, parentName, pair.second, childName,
+ null /* highlightableMenuKey*/));
}
}
// Done
return pairs;
}
+ public List<IndexData> updateIndexDataPayload(Context context, List<IndexData> indexData) {
+ final long startTime = System.currentTimeMillis();
+ final List<IndexData> updatedIndexData = new ArrayList<>(indexData);
+ for (IndexData row : indexData) {
+ String menuKey = row.highlightableMenuKey;
+ if (!TextUtils.isEmpty(menuKey)) {
+ // top level settings
+ continue;
+ }
+ menuKey = HighlightableMenu.getMenuKey(context, row);
+ if (TextUtils.isEmpty(menuKey)) {
+ continue;
+ }
+ updatedIndexData.remove(row);
+ updatedIndexData.add(row.mutate().setTopLevelMenuKey(menuKey).build());
+ }
+ Log.d(TAG, "Updating index data payload took: " + (System.currentTimeMillis() - startTime));
+ return updatedIndexData;
+ }
+
/**
* Return the conversion of {@link SearchIndexableRaw} to {@link IndexData}.
* The fields of {@link SearchIndexableRaw} are a subset of {@link IndexData},
* and there is some data sanitization in the conversion.
*/
@Nullable
- private IndexData convertRaw(Context context, String authority, SearchIndexableRaw raw,
+ private IndexData convertRaw(String authority, SearchIndexableRaw raw,
Set<String> nonIndexableKeys) {
if (TextUtils.isEmpty(raw.key)) {
Log.w(TAG, "Skipping null key for raw indexable " + authority + "/" + raw.title);
@@ -181,7 +206,7 @@
.setAuthority(authority)
.setKey(raw.key);
- return builder.build(context);
+ return builder.build();
}
/**
@@ -227,6 +252,7 @@
String keywords;
String headerKeywords;
String childFragment;
+ String highlightableMenuKey = null;
@DrawableRes int iconResId;
ResultPayload payload;
boolean enabled;
@@ -281,6 +307,11 @@
enabled = !nonIndexableKeys.contains(key);
keywords = XmlParserUtils.getDataKeywords(context, attrs);
iconResId = XmlParserUtils.getDataIcon(context, attrs);
+ if (TextUtils.equals(sir.packageName, SETTINGS_PACKAGE_NAME)
+ && SiteMapManager.isTopLevelSettings(sir.className)) {
+ highlightableMenuKey = XmlParserUtils.getHighlightableMenuKey(context, attrs);
+ }
+
if (isHeaderUnique && TextUtils.equals(headerTitle, title)) {
isHeaderUnique = false;
@@ -298,6 +329,8 @@
.setIntentTargetPackage(sir.intentTargetPackage)
.setIntentTargetClass(sir.intentTargetClass)
.setEnabled(enabled)
+ .setHighlightableMenuKey(highlightableMenuKey)
+ .setTopLevelMenuKey(highlightableMenuKey)
.setKey(key);
if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) {
@@ -354,7 +387,7 @@
private void tryAddIndexDataToList(List<IndexData> list, IndexData.Builder data) {
if (!TextUtils.isEmpty(data.getKey())) {
- list.add(data.build(mContext));
+ list.add(data.build());
} else {
Log.w(TAG, "Skipping index for null-key item " + data);
}
diff --git a/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java b/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
index b9211e7..cd61350 100644
--- a/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
+++ b/src/com/android/settings/intelligence/search/indexing/IndexDatabaseHelper.java
@@ -40,7 +40,7 @@
private static final String TAG = "IndexDatabaseHelper";
private static final String DATABASE_NAME = "search_index.db";
- private static final int DATABASE_VERSION = 120;
+ private static final int DATABASE_VERSION = 121;
@VisibleForTesting
static final String SHARED_PREFS_TAG = "indexing_manager";
@@ -75,6 +75,7 @@
String DATA_KEY_REF = "data_key_reference";
String PAYLOAD_TYPE = "payload_type";
String PAYLOAD = "payload";
+ String TOP_LEVEL_MENU_KEY = "top_level_menu_key";
}
public interface MetaColumns {
@@ -92,6 +93,7 @@
String CHILD_CLASS = "child_class";
String PARENT_TITLE = "parent_title";
String CHILD_TITLE = "child_title";
+ String HIGHLIGHTABLE_MENU_KEY = "highlightable_menu_key";
}
private static final String CREATE_INDEX_TABLE =
@@ -136,6 +138,8 @@
IndexColumns.PAYLOAD_TYPE +
", " +
IndexColumns.PAYLOAD +
+ ", " +
+ IndexColumns.TOP_LEVEL_MENU_KEY +
");";
private static final String CREATE_META_TABLE =
@@ -162,6 +166,8 @@
SiteMapColumns.PARENT_TITLE +
", " +
SiteMapColumns.CHILD_TITLE +
+ ", " +
+ SiteMapColumns.HIGHLIGHTABLE_MENU_KEY +
")";
private static final String INSERT_BUILD_VERSION =
"INSERT INTO " + Tables.TABLE_META_INDEX +
diff --git a/src/com/android/settings/intelligence/search/indexing/XmlParserUtils.java b/src/com/android/settings/intelligence/search/indexing/XmlParserUtils.java
index 4efbde1..d3e5c25 100644
--- a/src/com/android/settings/intelligence/search/indexing/XmlParserUtils.java
+++ b/src/com/android/settings/intelligence/search/indexing/XmlParserUtils.java
@@ -76,25 +76,7 @@
if (TextUtils.isEmpty(keywordRes)) {
return null;
}
- // The format of keyword is either a string, or @ followed by int (@123456).
- // When it's int, we need to look up the actual string from context.
- if (!keywordRes.startsWith("@")) {
- // It's a string.
- return keywordRes;
- } else {
- // It's a resource
- try {
- final int resValue = Integer.parseInt(keywordRes.substring(1));
- if (DevicePolicyResourcesUtils.isDevicePolicyResource(context, resValue)) {
- return DevicePolicyResourcesUtils.getDevicePolicyResource(context, resValue);
- } else {
- return context.getString(resValue);
- }
- } catch (NumberFormatException e) {
- Log.w(TAG, "Failed to parse keyword attribute, skipping " + keywordRes);
- return null;
- }
- }
+ return getString(context, keywordRes);
}
public static int getDataIcon(Context context, AttributeSet attrs) {
@@ -112,6 +94,17 @@
R.styleable.Preference_android_fragment);
}
+ /**
+ * Returns if the attrs contains highlightableMenuKey="" element.
+ */
+ public static String getHighlightableMenuKey(Context context, AttributeSet attrs) {
+ String menuKey = attrs.getAttributeValue(NS_APP_RES_AUTO, "highlightableMenuKey");
+ if (!TextUtils.isEmpty(menuKey)) {
+ menuKey = getString(context, menuKey);
+ }
+ return menuKey;
+ }
+
@Nullable
private static String getData(Context context, AttributeSet set, int[] attrs, int resId) {
final TypedArray ta = context.obtainStyledAttributes(set, attrs);
@@ -125,7 +118,6 @@
return data;
}
-
private static String getDataEntries(Context context, AttributeSet set, int[] attrs,
int resId) {
final TypedArray sa = context.obtainStyledAttributes(set, attrs);
@@ -148,4 +140,26 @@
}
return result.toString();
}
+
+ private static String getString(Context context, String res) {
+ // The format of the resource is either a string, or @ followed by int (@123456).
+ // When it's int, we need to look up the actual string from context.
+ if (!res.startsWith("@")) {
+ // It's a string.
+ return res;
+ } else {
+ // It's a resource
+ try {
+ final int resValue = Integer.parseInt(res.substring(1));
+ if (DevicePolicyResourcesUtils.isDevicePolicyResource(context, resValue)) {
+ return DevicePolicyResourcesUtils.getDevicePolicyResource(context, resValue);
+ } else {
+ return context.getString(resValue);
+ }
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Failed to parse keyword attribute, skipping " + res);
+ return null;
+ }
+ }
+ }
}
diff --git a/src/com/android/settings/intelligence/search/query/AccessibilityServiceResultTask.java b/src/com/android/settings/intelligence/search/query/AccessibilityServiceResultTask.java
index d6de496..05d0a54 100644
--- a/src/com/android/settings/intelligence/search/query/AccessibilityServiceResultTask.java
+++ b/src/com/android/settings/intelligence/search/query/AccessibilityServiceResultTask.java
@@ -16,6 +16,8 @@
package com.android.settings.intelligence.search.query;
+import static com.android.settings.intelligence.search.sitemap.HighlightableMenu.MENU_KEY_ACCESSIBILITY;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -85,9 +87,9 @@
final Drawable icon = serviceInfo.loadIcon(mPackageManager);
final String componentName = new ComponentName(serviceInfo.packageName,
serviceInfo.name).flattenToString();
- final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(mContext,
+ final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(
mContext.getString(R.string.accessibility_settings_classname),
- componentName, screenTitle);
+ componentName, screenTitle, MENU_KEY_ACCESSIBILITY);
results.add(new SearchResult.Builder()
.setTitle(title)
diff --git a/src/com/android/settings/intelligence/search/query/InputDeviceResultTask.java b/src/com/android/settings/intelligence/search/query/InputDeviceResultTask.java
index 4cad4cc..f4bd77d 100644
--- a/src/com/android/settings/intelligence/search/query/InputDeviceResultTask.java
+++ b/src/com/android/settings/intelligence/search/query/InputDeviceResultTask.java
@@ -16,6 +16,8 @@
package com.android.settings.intelligence.search.query;
+import static com.android.settings.intelligence.search.sitemap.HighlightableMenu.MENU_KEY_SYSTEM;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -108,8 +110,8 @@
if (wordDiff == NAME_NO_MATCH) {
continue;
}
- final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(mContext,
- PHYSICAL_KEYBOARD_FRAGMENT, deviceName, screenTitle);
+ final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(
+ PHYSICAL_KEYBOARD_FRAGMENT, deviceName, screenTitle, MENU_KEY_SYSTEM);
results.add(new SearchResult.Builder()
.setTitle(deviceName)
.setPayload(new ResultPayload(intent))
@@ -139,8 +141,8 @@
final ServiceInfo serviceInfo = info.getServiceInfo();
final String key = new ComponentName(serviceInfo.packageName, serviceInfo.name)
.flattenToString();
- final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(mContext,
- VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle);
+ final Intent intent = DatabaseIndexingUtils.buildSearchTrampolineIntent(
+ VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle, MENU_KEY_SYSTEM);
results.add(new SearchResult.Builder()
.setTitle(title)
.setSummary(summary)
diff --git a/src/com/android/settings/intelligence/search/query/InstalledAppResultTask.java b/src/com/android/settings/intelligence/search/query/InstalledAppResultTask.java
index 6732765..6d9060e 100644
--- a/src/com/android/settings/intelligence/search/query/InstalledAppResultTask.java
+++ b/src/com/android/settings/intelligence/search/query/InstalledAppResultTask.java
@@ -16,6 +16,8 @@
package com.android.settings.intelligence.search.query;
+import static com.android.settings.intelligence.search.sitemap.HighlightableMenu.MENU_KEY_APPS;
+
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -29,6 +31,7 @@
import com.android.settings.intelligence.search.ResultPayload;
import com.android.settings.intelligence.search.SearchResult;
import com.android.settings.intelligence.search.indexing.DatabaseIndexingUtils;
+import com.android.settings.intelligence.search.sitemap.HighlightableMenu;
import com.android.settings.intelligence.search.sitemap.SiteMapManager;
import java.util.ArrayList;
@@ -40,11 +43,11 @@
*/
public class InstalledAppResultTask extends SearchQueryTask.QueryWorker {
- public static final int QUERY_WORKER_ID =
+ private static final int QUERY_WORKER_ID =
SettingsIntelligenceLogProto.SettingsIntelligenceEvent.SEARCH_QUERY_INSTALLED_APPS;
+ private static final String INTENT_SCHEME = "package";
private final PackageManager mPackageManager;
- private final String INTENT_SCHEME = "package";
private List<String> mBreadcrumb;
public static SearchQueryTask newTask(Context context, SiteMapManager siteMapManager,
@@ -85,12 +88,14 @@
continue;
}
- final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ final Intent targetIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
- .setData(
- Uri.fromParts(INTENT_SCHEME, info.packageName, null /* fragment */))
+ .setData(Uri.fromParts(INTENT_SCHEME, info.packageName, null /* fragment */))
.putExtra(DatabaseIndexingUtils.EXTRA_SOURCE_METRICS_CATEGORY,
DatabaseIndexingUtils.DASHBOARD_SEARCH_RESULTS);
+ final Intent intent = HighlightableMenu.isFeatureEnabled(mContext)
+ ? DatabaseIndexingUtils.buildSearchTrampolineIntent(targetIntent, MENU_KEY_APPS)
+ : targetIntent;
final AppSearchResult.Builder builder = new AppSearchResult.Builder();
builder.setAppInfo(info)
diff --git a/src/com/android/settings/intelligence/search/sitemap/HighlightableMenu.java b/src/com/android/settings/intelligence/search/sitemap/HighlightableMenu.java
new file mode 100644
index 0000000..dc6a96a
--- /dev/null
+++ b/src/com/android/settings/intelligence/search/sitemap/HighlightableMenu.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 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.settings.intelligence.search.sitemap;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.settings.intelligence.overlay.FeatureFactory;
+import com.android.settings.intelligence.search.indexing.IndexData;
+import com.android.settingslib.activityembedding.ActivityEmbeddingUtils;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class HighlightableMenu {
+
+ private static final String TAG = "HighlightableMenu";
+ private static final boolean DEBUG = false;
+
+ public static final String MENU_KEY_NETWORK = "top_level_network";
+ public static final String MENU_KEY_APPS = "top_level_apps";
+ public static final String MENU_KEY_ACCESSIBILITY = "top_level_accessibility";
+ public static final String MENU_KEY_PRIVACY = "top_level_privacy";
+ public static final String MENU_KEY_SYSTEM = "top_level_system";
+
+ private static final Map<String, String> sAuthorityToMenuKeyMap;
+ private static final Map<String, String> sPackageToMenuKeyMap;
+
+ static {
+ sAuthorityToMenuKeyMap = new ArrayMap<>();
+ sAuthorityToMenuKeyMap.put(
+ "com.android.permissioncontroller.role", MENU_KEY_APPS); // Default apps
+
+ sPackageToMenuKeyMap = new ArrayMap<>();
+ sPackageToMenuKeyMap.put(
+ "com.android.settings.network", MENU_KEY_NETWORK); // Settings Network page
+ sPackageToMenuKeyMap.put(
+ "com.android.permissioncontroller", MENU_KEY_PRIVACY); // Permission manager
+ }
+
+ private HighlightableMenu() {
+ }
+
+ public static boolean isFeatureEnabled(Context context) {
+ boolean enabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context);
+ Log.i(TAG, "isFeatureEnabled: " + enabled);
+ return enabled;
+ }
+
+ public static String getMenuKey(Context context, IndexData row) {
+ String menuKey;
+ SiteMapManager siteMap = FeatureFactory.get(context).searchFeatureProvider()
+ .getSiteMapManager();
+
+ // look up in SiteMap
+ SiteMapPair pair = siteMap.getTopLevelPair(context, row.className, row.screenTitle);
+ if (pair != null) {
+ menuKey = pair.getHighlightableMenuKey();
+ if (!TextUtils.isEmpty(menuKey)) {
+ return menuKey;
+ }
+ }
+
+ // look up in custom authority map
+ menuKey = sAuthorityToMenuKeyMap.get(row.authority);
+ if (!TextUtils.isEmpty(menuKey)) {
+ logD("Matched authority, title: " + row.updatedTitle + ", menuKey: " + menuKey);
+ return menuKey;
+ }
+
+ // look up in custom package map (package match)
+ menuKey = sPackageToMenuKeyMap.get(row.packageName);
+ if (!TextUtils.isEmpty(menuKey)) {
+ logD("Matched package, title: " + row.updatedTitle + ", menuKey: " + menuKey);
+ return menuKey;
+ }
+
+ // look up in custom package map (target package match)
+ menuKey = sPackageToMenuKeyMap.get(row.intentTargetPackage);
+ if (!TextUtils.isEmpty(menuKey)) {
+ logD("Matched target package, title: " + row.updatedTitle + ", menuKey: " + menuKey);
+ return menuKey;
+ }
+
+ // look up in custom package map (class prefix match)
+ if (!TextUtils.isEmpty(row.className)) {
+ for (Entry<String, String> entry : sPackageToMenuKeyMap.entrySet()) {
+ if (row.className.startsWith(entry.getKey())) {
+ menuKey = entry.getValue();
+ if (!TextUtils.isEmpty(menuKey)) {
+ logD("Matched class prefix, title: " + row.updatedTitle
+ + ", menuKey: " + menuKey);
+ return menuKey;
+ }
+ }
+ }
+ }
+
+ logD("Cannot get menu key for: " + row.updatedTitle
+ + ", data key: " + row.key
+ + ", top-level: " + (pair != null ? pair.getParentTitle() : row.screenTitle)
+ + ", package: " + row.packageName);
+ return menuKey;
+ }
+
+ private static void logD(String log) {
+ if (DEBUG) {
+ Log.d(TAG, log);
+ }
+ }
+}
diff --git a/src/com/android/settings/intelligence/search/sitemap/SiteMapManager.java b/src/com/android/settings/intelligence/search/sitemap/SiteMapManager.java
index 6575cab..a6e76b5 100644
--- a/src/com/android/settings/intelligence/search/sitemap/SiteMapManager.java
+++ b/src/com/android/settings/intelligence/search/sitemap/SiteMapManager.java
@@ -32,13 +32,16 @@
public class SiteMapManager {
private static final String TAG = "SiteMapManager";
+ private static final String TOP_LEVEL_SETTINGS
+ = "com.android.settings.homepage.TopLevelSettings";
private static final boolean DEBUG_TIMING = false;
public static final String[] SITE_MAP_COLUMNS = {
SiteMapColumns.PARENT_CLASS,
SiteMapColumns.PARENT_TITLE,
SiteMapColumns.CHILD_CLASS,
- SiteMapColumns.CHILD_TITLE
+ SiteMapColumns.CHILD_TITLE,
+ SiteMapColumns.HIGHLIGHTABLE_MENU_KEY
};
private final List<SiteMapPair> mPairs = new ArrayList<>();
@@ -46,6 +49,13 @@
private boolean mInitialized;
/**
+ * Check whether the specified class is top level settings class.
+ */
+ public static boolean isTopLevelSettings(String clazz) {
+ return TextUtils.equals(TOP_LEVEL_SETTINGS, clazz);
+ }
+
+ /**
* Given a fragment class name and its screen title, build a breadcrumb from Settings root to
* this screen.
* <p/>
@@ -85,6 +95,48 @@
}
}
+ public synchronized SiteMapPair getTopLevelPair(Context context, String clazz,
+ String screenTitle) {
+ if (!mInitialized) {
+ init(context);
+ }
+
+ // find the default pair
+ SiteMapPair currentPair = null;
+ if (!TextUtils.isEmpty(clazz)) {
+ for (SiteMapPair pair : mPairs) {
+ if (TextUtils.equals(pair.getChildClass(), clazz)) {
+ currentPair = pair;
+ if (TextUtils.isEmpty(screenTitle)) {
+ screenTitle = pair.getChildTitle();
+ }
+ break;
+ }
+ }
+ }
+
+ // recursively find the top level pair
+ String currentClass = clazz;
+ String currentTitle = screenTitle;
+ while (true) {
+ // look up parent by class and title
+ SiteMapPair pair = lookUpParent(currentClass, currentTitle);
+ if (pair == null) {
+ // fallback option: look up parent only by title
+ pair = lookUpParent(currentTitle);
+ if (pair == null) {
+ return currentPair;
+ }
+ }
+ if (!TextUtils.isEmpty(pair.getHighlightableMenuKey())) {
+ return pair;
+ }
+ currentPair = pair;
+ currentClass = pair.getParentClass();
+ currentTitle = pair.getParentTitle();
+ }
+ }
+
/**
* Initialize a list of {@link SiteMapPair}s. Each pair knows about a single parent-child
* page relationship.
@@ -95,6 +147,12 @@
// Make sure only init once.
return;
}
+
+ // Will init again if site map table updated, need clear the old data if it's not empty.
+ if (!mPairs.isEmpty()) {
+ mPairs.clear();
+ }
+
final long startTime = System.currentTimeMillis();
// First load site map from static index table.
final Context appContext = context.getApplicationContext();
@@ -106,7 +164,9 @@
sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_CLASS)),
sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_TITLE)),
sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_CLASS)),
- sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_TITLE)));
+ sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_TITLE)),
+ sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.HIGHLIGHTABLE_MENU_KEY))
+ );
mPairs.add(pair);
}
sitemap.close();
@@ -128,4 +188,21 @@
return null;
}
+ @WorkerThread
+ private SiteMapPair lookUpParent(String title) {
+ if (TextUtils.isEmpty(title)) {
+ return null;
+ }
+ for (SiteMapPair pair : mPairs) {
+ if (TextUtils.equals(title, pair.getChildTitle())) {
+ return pair;
+ }
+ }
+ return null;
+ }
+
+ @WorkerThread
+ public void setInitialized(boolean initialized) {
+ mInitialized = initialized;
+ }
}
diff --git a/src/com/android/settings/intelligence/search/sitemap/SiteMapPair.java b/src/com/android/settings/intelligence/search/sitemap/SiteMapPair.java
index cf30dc4..a92f67b 100644
--- a/src/com/android/settings/intelligence/search/sitemap/SiteMapPair.java
+++ b/src/com/android/settings/intelligence/search/sitemap/SiteMapPair.java
@@ -33,13 +33,15 @@
private final String mParentTitle;
private final String mChildClass;
private final String mChildTitle;
+ private final String mHighlightableMenuKey;
- public SiteMapPair(String parentClass, String parentTitle, String childClass,
- String childTitle) {
+ public SiteMapPair(String parentClass, String parentTitle, String childClass, String childTitle,
+ String highlightableMenuKey) {
mParentClass = parentClass;
mParentTitle = parentTitle;
mChildClass = childClass;
mChildTitle = childTitle;
+ mHighlightableMenuKey = highlightableMenuKey;
}
@Override
@@ -72,6 +74,10 @@
return mChildTitle;
}
+ public String getHighlightableMenuKey() {
+ return mHighlightableMenuKey;
+ }
+
/**
* Converts this object into {@link ContentValues}. The content follows schema in
* {@link IndexDatabaseHelper.SiteMapColumns}.
@@ -83,6 +89,8 @@
values.put(IndexDatabaseHelper.SiteMapColumns.PARENT_TITLE, mParentTitle);
values.put(IndexDatabaseHelper.SiteMapColumns.CHILD_CLASS, mChildClass);
values.put(IndexDatabaseHelper.SiteMapColumns.CHILD_TITLE, mChildTitle);
+ values.put(IndexDatabaseHelper.SiteMapColumns.HIGHLIGHTABLE_MENU_KEY,
+ mHighlightableMenuKey);
return values;
}
}
diff --git a/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java b/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
index 2502e2a..c04e7d4 100644
--- a/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
+++ b/src/com/android/settings/intelligence/suggestions/model/CandidateSuggestion.java
@@ -230,8 +230,8 @@
.setSummary(summary)
.setFlags(flags)
.setIcon(icon)
- .setPendingIntent(PendingIntent
- .getActivity(mContext, 0 /* requestCode */, mIntent, 0 /* flags */));
+ .setPendingIntent(PendingIntent.getActivity(
+ mContext, 0 /* requestCode */, mIntent, PendingIntent.FLAG_IMMUTABLE));
}
/**
diff --git a/src/com/android/settings/intelligence/suggestions/ranking/SuggestionRanker.java b/src/com/android/settings/intelligence/suggestions/ranking/SuggestionRanker.java
index 61c08e9..f8faba0 100644
--- a/src/com/android/settings/intelligence/suggestions/ranking/SuggestionRanker.java
+++ b/src/com/android/settings/intelligence/suggestions/ranking/SuggestionRanker.java
@@ -40,15 +40,14 @@
// relevance metric for ranking the suggestion items. This model is learned with off-line data
// by training a binary classifier to detect the clicked items. The higher the obtained
// relevance metric, the higher chance of getting clicked.
- private static final Map<String, Double> WEIGHTS = new HashMap<String, Double>() {{
- put(SuggestionFeaturizer.FEATURE_IS_SHOWN, 5.05140842519);
- put(SuggestionFeaturizer.FEATURE_IS_DISMISSED, 2.29641455171);
- put(SuggestionFeaturizer.FEATURE_IS_CLICKED, -2.98812233623);
- put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN, 5.02807250202);
- put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED, 2.49589700842);
- put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED, -4.3377039948);
- put(SuggestionFeaturizer.FEATURE_SHOWN_COUNT, -2.35993512546);
- }};
+ private static final Map<String, Double> WEIGHTS = Map.of(
+ SuggestionFeaturizer.FEATURE_IS_SHOWN, 5.05140842519,
+ SuggestionFeaturizer.FEATURE_IS_DISMISSED, 2.29641455171,
+ SuggestionFeaturizer.FEATURE_IS_CLICKED, -2.98812233623,
+ SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN, 5.02807250202,
+ SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED, 2.49589700842,
+ SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED, -4.3377039948,
+ SuggestionFeaturizer.FEATURE_SHOWN_COUNT, -2.35993512546);
private final long mMaxSuggestionsDisplayCount;
private final SuggestionFeaturizer mSuggestionFeaturizer;