Merge "Build Intents at index time"

This commit is contained in:
TreeHugger Robot
2017-04-14 22:01:50 +00:00
committed by Android (Google) Code Review
23 changed files with 389 additions and 495 deletions

View File

@@ -14,14 +14,17 @@
package com.android.settings.display;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.util.ArrayMap;
import com.android.settings.core.PreferenceController;
import com.android.settings.search2.DatabaseIndexingUtils;
import com.android.settings.search2.InlineSwitchPayload;
import com.android.settings.search2.ResultPayload;
import com.android.settings.R;
import java.util.Map;
@@ -71,7 +74,11 @@ public class AutoBrightnessPreferenceController extends PreferenceController imp
valueMap.put(SCREEN_BRIGHTNESS_MODE_AUTOMATIC, true);
valueMap.put(SCREEN_BRIGHTNESS_MODE_MANUAL, false);
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
getClass().getName(), KEY_AUTO_BRIGHTNESS,
mContext.getString(R.string.display_settings));
return new InlineSwitchPayload(SCREEN_BRIGHTNESS_MODE,
ResultPayload.SettingsSource.SYSTEM, valueMap);
ResultPayload.SettingsSource.SYSTEM, valueMap, intent);
}
}

View File

@@ -17,21 +17,15 @@
package com.android.settings.search2;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.BadParcelableException;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.dashboard.SiteMapManager;
import java.util.ArrayList;
@@ -46,9 +40,6 @@ import java.util.Set;
import static com.android.settings.search2.DatabaseResultLoader.COLUMN_INDEX_CLASS_NAME;
import static com.android.settings.search2.DatabaseResultLoader.COLUMN_INDEX_ICON;
import static com.android.settings.search2.DatabaseResultLoader.COLUMN_INDEX_ID;
import static com.android.settings.search2.DatabaseResultLoader.COLUMN_INDEX_INTENT_ACTION;
import static com.android.settings.search2.DatabaseResultLoader
.COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS;
import static com.android.settings.search2.DatabaseResultLoader
.COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE;
import static com.android.settings.search2.DatabaseResultLoader.COLUMN_INDEX_KEY;
@@ -132,7 +123,6 @@ class CursorToSearchResultConverter {
mKeys.add(docId);
final String pkgName = cursor.getString(COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE);
final String action = cursor.getString(COLUMN_INDEX_INTENT_ACTION);
final String title = cursor.getString(COLUMN_INDEX_TITLE);
final String summaryOn = cursor.getString(COLUMN_INDEX_SUMMARY_ON);
final String className = cursor.getString(COLUMN_INDEX_CLASS_NAME);
@@ -140,16 +130,7 @@ class CursorToSearchResultConverter {
final String iconResStr = cursor.getString(COLUMN_INDEX_ICON);
final int payloadType = cursor.getInt(COLUMN_INDEX_PAYLOAD_TYPE);
final byte[] marshalledPayload = cursor.getBlob(COLUMN_INDEX_PAYLOAD);
final ResultPayload payload;
if (marshalledPayload != null) {
payload = getUnmarshalledPayload(marshalledPayload, payloadType);
} else if (payloadType == ResultPayload.PayloadType.INTENT) {
payload = getIntentPayload(cursor, action, key, className, pkgName);
} else {
Log.w(TAG, "Error creating payload - bad marshalling data or mismatched types");
return null;
}
final ResultPayload payload = getUnmarshalledPayload(marshalledPayload, payloadType);
final List<String> breadcrumbs = getBreadcrumbs(sitemapManager, cursor);
final int rank = getRank(title, breadcrumbs, baseRank, key);
@@ -196,34 +177,12 @@ class CursorToSearchResultConverter {
return icon;
}
private IntentPayload getIntentPayload(Cursor cursor, String action, String key,
String className, String pkgName ) {
IntentPayload payload;
if (TextUtils.isEmpty(action)) {
final String screenTitle = cursor.getString(COLUMN_INDEX_SCREEN_TITLE);
// Action is null, we will launch it as a sub-setting
final Bundle args = new Bundle();
args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
final Intent intent = Utils.onBuildStartFragmentIntent(mContext,
className, args, null, 0, screenTitle, false,
MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS);
payload = new IntentPayload(intent);
} else {
final Intent intent = new Intent(action);
final String targetClass = cursor.getString(COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS);
if (!TextUtils.isEmpty(pkgName) && !TextUtils.isEmpty(targetClass)) {
final ComponentName component = new ComponentName(pkgName, targetClass);
intent.setComponent(component);
}
intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
payload = new IntentPayload(intent);
}
return payload;
}
private ResultPayload getUnmarshalledPayload(byte[] unmarshalledPayload, int payloadType) {
try {
switch (payloadType) {
case ResultPayload.PayloadType.INTENT:
return ResultPayloadUtils.unmarshall(unmarshalledPayload,
ResultPayload.CREATOR);
case ResultPayload.PayloadType.INLINE_SWITCH:
return ResultPayloadUtils.unmarshall(unmarshalledPayload,
InlineSwitchPayload.CREATOR);
@@ -269,5 +228,4 @@ class CursorToSearchResultConverter {
}
return baseRank;
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.search2;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -39,6 +40,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceController;
import com.android.settings.search.IndexDatabaseHelper;
import com.android.settings.search.Indexable;
@@ -927,7 +929,7 @@ public class DatabaseIndexingManager {
.setNormalizedSummaryOff(normalizedSummaryOff)
.setSpaceDelimitedKeywords(spaceDelimitedKeywords);
updateOneRow(database, builder.build());
updateOneRow(database, builder.build(mContext));
}
private void updateOneRow(SQLiteDatabase database, DatabaseRow row) {
@@ -1212,7 +1214,45 @@ public class DatabaseIndexingManager {
return this;
}
public DatabaseRow build() {
/**
* Adds intent to inline payloads, or creates an Intent Payload as a fallback if the
* payload is null.
*/
private void setIntent(Context context) {
if (mPayload != null) {
return;
}
final Intent intent = buildIntent(context);
mPayload = new ResultPayload(intent);
mPayloadType = ResultPayload.PayloadType.INTENT;
}
/**
* Adds Intent payload to builder.
*/
private Intent buildIntent(Context context) {
final Intent intent;
if (TextUtils.isEmpty(mIntentAction)) {
// Action is null, we will launch it as a sub-setting
intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey,
mScreenTitle);
} else {
intent = new Intent(mIntentAction);
final String targetClass = mIntentTargetClass;
if (!TextUtils.isEmpty(mIntentTargetPackage)
&& !TextUtils.isEmpty(targetClass)) {
final ComponentName component = new ComponentName(mIntentTargetPackage,
targetClass);
intent.setComponent(component);
}
intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, mKey);
}
return intent;
}
public DatabaseRow build(Context context) {
setIntent(context);
return new DatabaseRow(this);
}
}

View File

@@ -19,15 +19,20 @@ package com.android.settings.search2;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceController;
import com.android.settings.search.Indexable;
@@ -57,6 +62,18 @@ public class DatabaseIndexingUtils {
private static final Pattern REMOVE_DIACRITICALS_PATTERN
= Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
/**
* Builds intent into a subsetting.
*/
public static Intent buildSubsettingIntent(Context context, String className, String key,
String screenTitle) {
final Bundle args = new Bundle();
args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
return Utils.onBuildStartFragmentIntent(context,
className, args, null, 0, screenTitle, false,
MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS);
}
/**
* @param className which wil provide the map between from {@link Uri}s to
* {@link PreferenceController}

View File

@@ -16,6 +16,8 @@
package com.android.settings.search2;
import android.content.Intent;
/**
* Abstract Payload for inline settings results.
*/
@@ -35,7 +37,9 @@ public abstract class InlinePayload extends ResultPayload {
*/
@SettingsSource public int settingSource;
public InlinePayload(String uri, @PayloadType int type, @SettingsSource int source) {
public InlinePayload(String uri, @PayloadType int type, @SettingsSource int source,
Intent intent) {
super(intent);
settingsUri = uri;
inlineType = type;
settingSource = source;

View File

@@ -18,6 +18,7 @@
package com.android.settings.search2;
import android.content.Context;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Settings;
@@ -38,14 +39,15 @@ public class InlineSwitchPayload extends InlinePayload {
public final Map<Integer, Boolean> valueMap;
public InlineSwitchPayload(String newUri, @SettingsSource int settingsSource,
Map<Integer, Boolean> map) {
super(newUri, PayloadType.INLINE_SWITCH, settingsSource);
Map<Integer, Boolean> map, Intent intent) {
super(newUri, PayloadType.INLINE_SWITCH, settingsSource, intent);
valueMap = map;
}
private InlineSwitchPayload(Parcel in) {
super(in.readString() /* Uri */ , in.readInt() /* Payload Type */,
in.readInt() /* Settings Source */);
in.readInt() /* Settings Source */,
(Intent) in.readParcelable(Intent.class.getClassLoader()) /* Intent */);
valueMap = in.readHashMap(Integer.class.getClassLoader());
}
@@ -64,6 +66,7 @@ public class InlineSwitchPayload extends InlinePayload {
dest.writeString(settingsUri);
dest.writeInt(inlineType);
dest.writeInt(settingSource);
dest.writeParcelable(mIntent, flags);
dest.writeMap(valueMap);
}

View File

@@ -34,7 +34,6 @@ import com.android.settings.SettingsActivity;
import com.android.settings.applications.ManageApplications;
import com.android.settings.applications.PackageManagerWrapper;
import com.android.settings.dashboard.SiteMapManager;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.utils.AsyncLoader;
import java.util.ArrayList;
@@ -98,7 +97,7 @@ public class InstalledAppResultLoader extends AsyncLoader<List<? extends SearchR
.addTitle(info.loadLabel(pm))
.addRank(getRank(wordDiff))
.addBreadcrumbs(getBreadCrumb())
.addPayload(new IntentPayload(intent));
.addPayload(new ResultPayload(intent));
results.add(builder.build());
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright (C) 2016 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.search2;
import android.content.Intent;
import android.os.Parcel;
/**
* Encapsulates the standard intent based results as seen in first party apps and Settings results.
*/
public class IntentPayload extends ResultPayload {
public final Intent intent;
private IntentPayload(Parcel in) {
intent = in.readParcelable(IntentPayload.class.getClassLoader());
}
public IntentPayload(Intent newIntent) {
intent = newIntent;
}
@ResultPayload.PayloadType public int getType() {
return PayloadType.INTENT;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(intent, flags);
}
public static final Creator<IntentPayload> CREATOR = new Creator<IntentPayload>() {
@Override
public IntentPayload createFromParcel(Parcel in) {
return new IntentPayload(in);
}
@Override
public IntentPayload[] newArray(int size) {
return new IntentPayload[size];
}
};
}

View File

@@ -40,7 +40,7 @@ public class IntentSearchViewHolder extends SearchViewHolder {
itemView.setOnClickListener(v -> {
fragment.onSearchResultClicked();
final Intent intent = ((IntentPayload) result.payload).intent;
final Intent intent = result.payload.getIntent();
final ComponentName cn = intent.getComponent();
final Pair<Integer, Object> rank = Pair.create(
MetricsEvent.FIELD_SETTINGS_SERACH_RESULT_RANK, getAdapterPosition());

View File

@@ -17,6 +17,8 @@
package com.android.settings.search2;
import android.annotation.IntDef;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
@@ -26,14 +28,15 @@ import java.lang.annotation.RetentionPolicy;
* A interface for search results types. Examples include Inline results, third party apps
* or any future possibilities.
*/
public abstract class ResultPayload implements Parcelable {
public class ResultPayload implements Parcelable {
protected final Intent mIntent;
@IntDef({PayloadType.INLINE_SLIDER, PayloadType.INLINE_SWITCH,
PayloadType.INTENT, PayloadType.SAVED_QUERY})
@Retention(RetentionPolicy.SOURCE)
public @interface PayloadType {
/**
* Resulting page will be started using an intent
* Resulting page will be started using an mIntent
*/
int INTENT = 0;
@@ -64,6 +67,42 @@ public abstract class ResultPayload implements Parcelable {
}
private ResultPayload(Parcel in) {
mIntent = in.readParcelable(ResultPayload.class.getClassLoader());
}
public ResultPayload(Intent intent) {
mIntent = intent;
}
@ResultPayload.PayloadType
public abstract int getType();
public int getType() {
return PayloadType.INTENT;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mIntent, flags);
}
public static final Creator<ResultPayload> CREATOR = new Creator<ResultPayload>() {
@Override
public ResultPayload createFromParcel(Parcel in) {
return new ResultPayload(in);
}
@Override
public ResultPayload[] newArray(int size) {
return new ResultPayload[size];
}
};
public Intent getIntent() {
return mIntent;
}
}

View File

@@ -27,11 +27,13 @@ public class SavedQueryPayload extends ResultPayload {
public final String query;
public SavedQueryPayload(String query) {
super(null /* Intent */);
this.query = query;
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
SavedQueryPayload(Parcel in) {
super(null /* Intent */);
query = in.readString();
}