508 lines
15 KiB
Java
508 lines
15 KiB
Java
/*
|
|
* Copyright (C) 2020 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 android.app.search;
|
|
|
|
import android.annotation.FloatRange;
|
|
import android.annotation.IntDef;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.StringDef;
|
|
import android.annotation.SystemApi;
|
|
import android.app.slice.SliceManager;
|
|
import android.appwidget.AppWidgetProviderInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.ShortcutInfo;
|
|
import android.content.pm.ShortcutManager;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.os.UserHandle;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* A representation of a search result. Search result can be expressed in one of the following:
|
|
* app icon, shortcut, slice, widget, or a custom object using {@link SearchAction}. While
|
|
* app icon ({@link PackageManager}, shortcut {@link ShortcutManager}, slice {@link SliceManager},
|
|
* or widget (@link AppWidgetManager} are published content backed by the system service,
|
|
* {@link SearchAction} is a custom object that the service can use to send search result to the
|
|
* client.
|
|
*
|
|
* These various types of Android primitives could be defined as {@link SearchResultType}. Some
|
|
* times, the result type can define the layout type that that this object can be rendered in.
|
|
* (e.g., app widget). Most times, {@link #getLayoutType()} assigned by the service
|
|
* can recommend which layout this target should be rendered in.
|
|
*
|
|
* The service can also use fields such as {@link #getScore()} to indicate
|
|
* how confidence the search result is and {@link #isHidden()} to indicate
|
|
* whether it is recommended to be shown by default.
|
|
*
|
|
* Finally, {@link #getId()} is the unique identifier of this search target and a single
|
|
* search target is defined by being able to express a single launcheable item. In case the
|
|
* service want to recommend how to combine multiple search target objects to render in a group
|
|
* (e.g., same row), {@link #getParentId()} can be assigned on the sub targets of the group
|
|
* using the primary search target's identifier.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public final class SearchTarget implements Parcelable {
|
|
|
|
public static final int RESULT_TYPE_APPLICATION = 1 << 0;
|
|
public static final int RESULT_TYPE_SHORTCUT = 1 << 1;
|
|
public static final int RESULT_TYPE_SLICE = 1 << 2;
|
|
public static final int RESULT_TYPE_WIDGETS = 1 << 3;
|
|
|
|
// ------
|
|
// | icon |
|
|
// ------
|
|
// text
|
|
public static final String LAYOUT_TYPE_ICON = "icon";
|
|
|
|
// ------ ------ ------
|
|
// | | title |(opt)| |(opt)|
|
|
// | icon | subtitle (optional) | icon| | icon|
|
|
// ------ ------ ------
|
|
public static final String LAYOUT_TYPE_ICON_ROW = "icon_row";
|
|
|
|
// ------
|
|
// | icon | title / subtitle (optional)
|
|
// ------
|
|
public static final String LAYOUT_TYPE_SHORT_ICON_ROW = "short_icon_row";
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
@IntDef(prefix = {"RESULT_TYPE_"}, value = {
|
|
RESULT_TYPE_APPLICATION,
|
|
RESULT_TYPE_SHORTCUT,
|
|
RESULT_TYPE_SLICE,
|
|
RESULT_TYPE_WIDGETS
|
|
})
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface SearchResultType {}
|
|
private final int mResultType;
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
@StringDef(prefix = {"LAYOUT_TYPE_"}, value = {
|
|
LAYOUT_TYPE_ICON,
|
|
LAYOUT_TYPE_ICON_ROW,
|
|
LAYOUT_TYPE_SHORT_ICON_ROW,
|
|
})
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface SearchLayoutType {}
|
|
|
|
/**
|
|
* Constant to express how the group of {@link SearchTarget} should be rendered on
|
|
* the client side. (e.g., "icon", "icon_row", "short_icon_row")
|
|
*/
|
|
@NonNull
|
|
private final String mLayoutType;
|
|
|
|
@NonNull
|
|
private final String mId;
|
|
|
|
@Nullable
|
|
private String mParentId;
|
|
|
|
private final float mScore;
|
|
|
|
private final boolean mHidden;
|
|
|
|
@NonNull
|
|
private final String mPackageName;
|
|
@NonNull
|
|
private final UserHandle mUserHandle;
|
|
@Nullable
|
|
private final SearchAction mSearchAction;
|
|
@Nullable
|
|
private final ShortcutInfo mShortcutInfo;
|
|
@Nullable
|
|
private final AppWidgetProviderInfo mAppWidgetProviderInfo;
|
|
@Nullable
|
|
private final Uri mSliceUri;
|
|
|
|
@NonNull
|
|
private final Bundle mExtras;
|
|
|
|
private SearchTarget(Parcel parcel) {
|
|
mResultType = parcel.readInt();
|
|
mLayoutType = parcel.readString();
|
|
mId = parcel.readString();
|
|
mParentId = parcel.readString();
|
|
mScore = parcel.readFloat();
|
|
mHidden = parcel.readBoolean();
|
|
|
|
mPackageName = parcel.readString();
|
|
mUserHandle = UserHandle.of(parcel.readInt());
|
|
mSearchAction = parcel.readTypedObject(SearchAction.CREATOR);
|
|
mShortcutInfo = parcel.readTypedObject(ShortcutInfo.CREATOR);
|
|
mAppWidgetProviderInfo = parcel.readTypedObject(AppWidgetProviderInfo.CREATOR);
|
|
mSliceUri = parcel.readTypedObject(Uri.CREATOR);
|
|
mExtras = parcel.readBundle(getClass().getClassLoader());
|
|
}
|
|
|
|
private SearchTarget(
|
|
int resultType,
|
|
@NonNull String layoutType,
|
|
@NonNull String id,
|
|
@Nullable String parentId,
|
|
float score, boolean hidden,
|
|
@NonNull String packageName,
|
|
@NonNull UserHandle userHandle,
|
|
@Nullable SearchAction action,
|
|
@Nullable ShortcutInfo shortcutInfo,
|
|
@Nullable Uri sliceUri,
|
|
@Nullable AppWidgetProviderInfo appWidgetProviderInfo,
|
|
@NonNull Bundle extras) {
|
|
mResultType = resultType;
|
|
mLayoutType = Objects.requireNonNull(layoutType);
|
|
mId = Objects.requireNonNull(id);
|
|
mParentId = parentId;
|
|
mScore = score;
|
|
mHidden = hidden;
|
|
mPackageName = Objects.requireNonNull(packageName);
|
|
mUserHandle = Objects.requireNonNull(userHandle);
|
|
mSearchAction = action;
|
|
mShortcutInfo = shortcutInfo;
|
|
mAppWidgetProviderInfo = appWidgetProviderInfo;
|
|
mSliceUri = sliceUri;
|
|
mExtras = extras != null ? extras : new Bundle();
|
|
}
|
|
|
|
/**
|
|
* Retrieves the result type {@see SearchResultType}.
|
|
*/
|
|
public @SearchResultType int getResultType() {
|
|
return mResultType;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the layout type.
|
|
*/
|
|
@NonNull
|
|
public @SearchLayoutType String getLayoutType() {
|
|
return mLayoutType;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the id of the target.
|
|
*/
|
|
@NonNull
|
|
public String getId() {
|
|
return mId;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the parent id of the target.
|
|
*/
|
|
@NonNull
|
|
public String getParentId() {
|
|
return mParentId;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the score of the target.
|
|
*/
|
|
public float getScore() {
|
|
return mScore;
|
|
}
|
|
|
|
/**
|
|
* Indicates whether this object should be hidden and shown only on demand.
|
|
*
|
|
* @deprecated will be removed once SDK drops
|
|
* @removed
|
|
*/
|
|
@Deprecated
|
|
public boolean shouldHide() {
|
|
return mHidden;
|
|
}
|
|
|
|
/**
|
|
* Indicates whether this object should be hidden and shown only on demand.
|
|
*/
|
|
public boolean isHidden() {
|
|
return mHidden;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the package name of the target.
|
|
*/
|
|
@NonNull
|
|
public String getPackageName() {
|
|
return mPackageName;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the user handle of the target.
|
|
*/
|
|
@NonNull
|
|
public UserHandle getUserHandle() {
|
|
return mUserHandle;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the shortcut info of the target.
|
|
*/
|
|
@Nullable
|
|
public ShortcutInfo getShortcutInfo() {
|
|
return mShortcutInfo;
|
|
}
|
|
|
|
/**
|
|
* Return a widget provider info.
|
|
*/
|
|
@Nullable
|
|
public AppWidgetProviderInfo getAppWidgetProviderInfo() {
|
|
return mAppWidgetProviderInfo;
|
|
}
|
|
|
|
/**
|
|
* Returns a slice uri.
|
|
*/
|
|
@Nullable
|
|
public Uri getSliceUri() {
|
|
return mSliceUri;
|
|
}
|
|
|
|
/**
|
|
* Returns a search action.
|
|
*/
|
|
@Nullable
|
|
public SearchAction getSearchAction() {
|
|
return mSearchAction;
|
|
}
|
|
|
|
/**
|
|
* Return extra bundle.
|
|
*/
|
|
@NonNull
|
|
public Bundle getExtras() {
|
|
return mExtras;
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel parcel, int flags) {
|
|
parcel.writeInt(mResultType);
|
|
parcel.writeString(mLayoutType);
|
|
parcel.writeString(mId);
|
|
parcel.writeString(mParentId);
|
|
parcel.writeFloat(mScore);
|
|
parcel.writeBoolean(mHidden);
|
|
parcel.writeString(mPackageName);
|
|
parcel.writeInt(mUserHandle.getIdentifier());
|
|
parcel.writeTypedObject(mSearchAction, flags);
|
|
parcel.writeTypedObject(mShortcutInfo, flags);
|
|
parcel.writeTypedObject(mAppWidgetProviderInfo, flags);
|
|
parcel.writeTypedObject(mSliceUri, flags);
|
|
parcel.writeBundle(mExtras);
|
|
}
|
|
|
|
/**
|
|
* @see Parcelable.Creator
|
|
*/
|
|
@NonNull
|
|
public static final Parcelable.Creator<SearchTarget> CREATOR =
|
|
new Parcelable.Creator<SearchTarget>() {
|
|
public SearchTarget createFromParcel(Parcel parcel) {
|
|
return new SearchTarget(parcel);
|
|
}
|
|
|
|
public SearchTarget[] newArray(int size) {
|
|
return new SearchTarget[size];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A builder for search target object.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public static final class Builder {
|
|
private int mResultType;
|
|
@NonNull
|
|
private String mLayoutType;
|
|
@NonNull
|
|
private String mId;
|
|
@Nullable
|
|
private String mParentId;
|
|
private float mScore;
|
|
private boolean mHidden;
|
|
@NonNull
|
|
private String mPackageName;
|
|
@NonNull
|
|
private UserHandle mUserHandle;
|
|
@Nullable
|
|
private SearchAction mSearchAction;
|
|
@Nullable
|
|
private ShortcutInfo mShortcutInfo;
|
|
@Nullable
|
|
private Uri mSliceUri;
|
|
@Nullable
|
|
private AppWidgetProviderInfo mAppWidgetProviderInfo;
|
|
@NonNull
|
|
private Bundle mExtras;
|
|
|
|
public Builder(@SearchResultType int resultType,
|
|
@SearchLayoutType @NonNull String layoutType,
|
|
@NonNull String id) {
|
|
mId = id;
|
|
mLayoutType = Objects.requireNonNull(layoutType);
|
|
mResultType = resultType;
|
|
mScore = 1f;
|
|
mHidden = false;
|
|
}
|
|
|
|
/**
|
|
* Sets the parent id.
|
|
*/
|
|
@NonNull
|
|
public Builder setParentId(@NonNull String parentId) {
|
|
mParentId = Objects.requireNonNull(parentId);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the package name.
|
|
*/
|
|
@NonNull
|
|
public Builder setPackageName(@NonNull String packageName) {
|
|
mPackageName = Objects.requireNonNull(packageName);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the user handle.
|
|
*/
|
|
@NonNull
|
|
public Builder setUserHandle(@NonNull UserHandle userHandle) {
|
|
mUserHandle = Objects.requireNonNull(userHandle);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the shortcut info.
|
|
*/
|
|
@NonNull
|
|
public Builder setShortcutInfo(@NonNull ShortcutInfo shortcutInfo) {
|
|
mShortcutInfo = Objects.requireNonNull(shortcutInfo);
|
|
if (mPackageName != null && !mPackageName.equals(shortcutInfo.getPackage())) {
|
|
throw new IllegalStateException("SearchTarget packageName is different from "
|
|
+ "shortcut's packageName");
|
|
}
|
|
mPackageName = shortcutInfo.getPackage();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the app widget provider info.
|
|
*/
|
|
@NonNull
|
|
public Builder setAppWidgetProviderInfo(
|
|
@NonNull AppWidgetProviderInfo appWidgetProviderInfo) {
|
|
mAppWidgetProviderInfo = Objects.requireNonNull(appWidgetProviderInfo);
|
|
if (mPackageName != null
|
|
&& !mPackageName.equals(appWidgetProviderInfo.provider.getPackageName())) {
|
|
throw new IllegalStateException("SearchTarget packageName is different from "
|
|
+ "appWidgetProviderInfo's packageName");
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the slice URI.
|
|
*/
|
|
@NonNull
|
|
public Builder setSliceUri(@NonNull Uri sliceUri) {
|
|
mSliceUri = sliceUri;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the {@link SearchAction} object to this target.
|
|
*/
|
|
@NonNull
|
|
public Builder setSearchAction(@Nullable SearchAction searchAction) {
|
|
mSearchAction = searchAction;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set any extra information that needs to be shared between service and the client.
|
|
*/
|
|
@NonNull
|
|
public Builder setExtras(@NonNull Bundle extras) {
|
|
mExtras = Objects.requireNonNull(extras);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the score of the object.
|
|
*/
|
|
@NonNull
|
|
public Builder setScore(@FloatRange(from = 0.0f, to = 1.0f) float score) {
|
|
mScore = score;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the result should be hidden (e.g. not visible) by default inside client.
|
|
*/
|
|
@NonNull
|
|
public Builder setHidden(boolean hidden) {
|
|
mHidden = hidden;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the result should be hidden by default inside client.
|
|
* @deprecated will be removed once SDK drops
|
|
* @removed
|
|
*/
|
|
@NonNull
|
|
@Deprecated
|
|
public Builder setShouldHide(boolean shouldHide) {
|
|
mHidden = shouldHide;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Builds a new SearchTarget instance.
|
|
*
|
|
* @throws IllegalStateException if no target is set
|
|
*/
|
|
@NonNull
|
|
public SearchTarget build() {
|
|
return new SearchTarget(mResultType, mLayoutType, mId, mParentId, mScore, mHidden,
|
|
mPackageName, mUserHandle,
|
|
mSearchAction, mShortcutInfo, mSliceUri, mAppWidgetProviderInfo,
|
|
mExtras);
|
|
}
|
|
}
|
|
}
|