Refine TC request classes.

Centrialize SystemTextClassifier fields into a class, e.g. userId,
useDefault, callingPackageName. Then all the TextClassifer request
should contain this class object. This helps to scalability if we
want to add new fields.

Bug: 149080832
Test: atest FrameworksCoreTests:android.view.textclassifier
Test: atest FrameworksCoreTests:android.widget.TextViewActivityTest
Test: atest CtsTextClassifierTestCases
Test: Manual. Check the parameters are expected when doing smart
selection, smart linkfy.
Change-Id: I224208adac333e2da7b4213f0905f6fb0abb8b2e

Change-Id: Iaef82c1d6ec8893888258820ac103f1b988eecfa
This commit is contained in:
Joanne Chung
2020-03-04 19:03:11 +08:00
parent aff8656fd2
commit 97d3a45453
16 changed files with 432 additions and 440 deletions

View File

@@ -21,15 +21,12 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.UserIdInt;
import android.app.Person;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.SpannedString;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
@@ -317,13 +314,9 @@ public final class ConversationActions implements Parcelable {
@NonNull
@Hint
private final List<String> mHints;
@Nullable
private String mCallingPackageName;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
@NonNull
private Bundle mExtras;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
private Request(
@NonNull List<Message> conversation,
@@ -345,10 +338,8 @@ public final class ConversationActions implements Parcelable {
int maxSuggestions = in.readInt();
List<String> hints = new ArrayList<>();
in.readStringList(hints);
String callingPackageName = in.readString();
int userId = in.readInt();
Bundle extras = in.readBundle();
boolean useDefaultTextClassifier = in.readBoolean();
SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
Request request = new Request(
conversation,
@@ -356,9 +347,7 @@ public final class ConversationActions implements Parcelable {
maxSuggestions,
hints,
extras);
request.setCallingPackageName(callingPackageName);
request.setUserId(userId);
request.setUseDefaultTextClassifier(useDefaultTextClassifier);
request.setSystemTextClassifierMetadata(systemTcMetadata);
return request;
}
@@ -368,10 +357,8 @@ public final class ConversationActions implements Parcelable {
parcel.writeParcelable(mTypeConfig, flags);
parcel.writeInt(mMaxSuggestions);
parcel.writeStringList(mHints);
parcel.writeString(mCallingPackageName);
parcel.writeInt(mUserId);
parcel.writeBundle(mExtras);
parcel.writeBoolean(mUseDefaultTextClassifier);
parcel.writeParcelable(mSystemTcMetadata, flags);
}
@Override
@@ -420,63 +407,32 @@ public final class ConversationActions implements Parcelable {
return mHints;
}
/**
* Sets the name of the package that is sending this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setCallingPackageName(@Nullable String callingPackageName) {
mCallingPackageName = callingPackageName;
}
/**
* Returns the name of the package that sent this request.
* This returns {@code null} if no calling package name is set.
*/
@Nullable
public String getCallingPackageName() {
return mCallingPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : null;
}
/**
* Sets the id of the user that sent this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of the user that sent this request.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcData) {
mSystemTcMetadata = systemTcData;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**

View File

@@ -19,10 +19,8 @@ package android.view.textclassifier;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.view.textclassifier.TextClassifier.EntityType;
import android.view.textclassifier.TextClassifier.WidgetType;
@@ -129,7 +127,6 @@ public final class SelectionEvent implements Parcelable {
private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
private @InvocationMethod int mInvocationMethod;
@Nullable private String mWidgetVersion;
private @UserIdInt int mUserId = UserHandle.USER_NULL;
@Nullable private String mResultId;
private long mEventTime;
private long mDurationSinceSessionStart;
@@ -140,7 +137,7 @@ public final class SelectionEvent implements Parcelable {
private int mEnd;
private int mSmartStart;
private int mSmartEnd;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
SelectionEvent(
int start, int end,
@@ -161,6 +158,7 @@ public final class SelectionEvent implements Parcelable {
mEventType = in.readInt();
mEntityType = in.readString();
mWidgetVersion = in.readInt() > 0 ? in.readString() : null;
// TODO: remove mPackageName once aiai does not need it
mPackageName = in.readString();
mWidgetType = in.readString();
mInvocationMethod = in.readInt();
@@ -175,8 +173,7 @@ public final class SelectionEvent implements Parcelable {
mEnd = in.readInt();
mSmartStart = in.readInt();
mSmartEnd = in.readInt();
mUserId = in.readInt();
mUseDefaultTextClassifier = in.readBoolean();
mSystemTcMetadata = in.readParcelable(null);
}
@Override
@@ -189,6 +186,7 @@ public final class SelectionEvent implements Parcelable {
if (mWidgetVersion != null) {
dest.writeString(mWidgetVersion);
}
// TODO: remove mPackageName once aiai does not need it
dest.writeString(mPackageName);
dest.writeString(mWidgetType);
dest.writeInt(mInvocationMethod);
@@ -205,8 +203,7 @@ public final class SelectionEvent implements Parcelable {
dest.writeInt(mEnd);
dest.writeInt(mSmartStart);
dest.writeInt(mSmartEnd);
dest.writeInt(mUserId);
dest.writeBoolean(mUseDefaultTextClassifier);
dest.writeParcelable(mSystemTcMetadata, flags);
}
@Override
@@ -409,45 +406,26 @@ public final class SelectionEvent implements Parcelable {
*/
@NonNull
public String getPackageName() {
return mPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : "";
}
/**
* Sets the id of this event's user.
* <p>
* Package-private for SystemTextClassifier's use.
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of this event's user.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -476,7 +454,7 @@ public final class SelectionEvent implements Parcelable {
mPackageName = context.getPackageName();
mWidgetType = context.getWidgetType();
mWidgetVersion = context.getWidgetVersion();
mUserId = context.getUserId();
mSystemTcMetadata = context.getSystemTextClassifierMetadata();
}
/**
@@ -663,10 +641,9 @@ public final class SelectionEvent implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
mWidgetVersion, mPackageName, mUserId, mWidgetType, mInvocationMethod, mResultId,
mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod, mResultId,
mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd,
mUseDefaultTextClassifier);
mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd, mSystemTcMetadata);
}
@Override
@@ -685,7 +662,6 @@ public final class SelectionEvent implements Parcelable {
&& Objects.equals(mEntityType, other.mEntityType)
&& Objects.equals(mWidgetVersion, other.mWidgetVersion)
&& Objects.equals(mPackageName, other.mPackageName)
&& mUserId == other.mUserId
&& Objects.equals(mWidgetType, other.mWidgetType)
&& mInvocationMethod == other.mInvocationMethod
&& Objects.equals(mResultId, other.mResultId)
@@ -698,7 +674,7 @@ public final class SelectionEvent implements Parcelable {
&& mEnd == other.mEnd
&& mSmartStart == other.mSmartStart
&& mSmartEnd == other.mSmartEnd
&& mUseDefaultTextClassifier == other.mUseDefaultTextClassifier;
&& mSystemTcMetadata == other.mSystemTcMetadata;
}
@Override
@@ -706,15 +682,14 @@ public final class SelectionEvent implements Parcelable {
return String.format(Locale.US,
"SelectionEvent {absoluteStart=%d, absoluteEnd=%d, eventType=%d, entityType=%s, "
+ "widgetVersion=%s, packageName=%s, widgetType=%s, invocationMethod=%s, "
+ "userId=%d, resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
+ "resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
+ "durationSincePreviousEvent=%d, eventIndex=%d,"
+ "sessionId=%s, start=%d, end=%d, smartStart=%d, smartEnd=%d, "
+ "mUseDefaultTextClassifier=%b}",
+ "systemTcMetadata=%s}",
mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod,
mUserId, mResultId, mEventTime, mDurationSinceSessionStart,
mDurationSincePreviousEvent, mEventIndex,
mSessionId, mStart, mEnd, mSmartStart, mSmartEnd, mUseDefaultTextClassifier);
mResultId, mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd, mSystemTcMetadata);
}
public static final @android.annotation.NonNull Creator<SelectionEvent> CREATOR = new Creator<SelectionEvent>() {

View File

@@ -18,7 +18,6 @@ package android.view.textclassifier;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.content.Context;
import android.os.Bundle;
@@ -39,7 +38,8 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Proxy to the system's default TextClassifier.
* proxy to the request to TextClassifierService via the TextClassificationManagerService.
*
* @hide
*/
@VisibleForTesting(visibility = Visibility.PACKAGE)
@@ -50,14 +50,19 @@ public final class SystemTextClassifier implements TextClassifier {
private final ITextClassifierService mManagerService;
private final TextClassificationConstants mSettings;
private final TextClassifier mFallback;
private final String mPackageName;
// NOTE: Always set this before sending a request to the manager service otherwise the manager
// service will throw a remote exception.
@UserIdInt
private final int mUserId;
private final boolean mUseDefault;
private TextClassificationSessionId mSessionId;
// NOTE: Always set this before sending a request to the manager service otherwise the
// manager service will throw a remote exception.
@NonNull
private final SystemTextClassifierMetadata mSystemTcMetadata;
/**
* Constructor of {@link SystemTextClassifier}
*
* @param context the context of the request.
* @param settings TextClassifier specific settings.
* @param useDefault whether to use the default text classifier to handle this request
*/
public SystemTextClassifier(
Context context,
TextClassificationConstants settings,
@@ -66,9 +71,11 @@ public final class SystemTextClassifier implements TextClassifier {
ServiceManager.getServiceOrThrow(Context.TEXT_CLASSIFICATION_SERVICE));
mSettings = Objects.requireNonNull(settings);
mFallback = TextClassifier.NO_OP;
mPackageName = Objects.requireNonNull(context.getOpPackageName());
mUserId = context.getUserId();
mUseDefault = useDefault;
// NOTE: Always set this before sending a request to the manager service otherwise the
// manager service will throw a remote exception.
mSystemTcMetadata = new SystemTextClassifierMetadata(
Objects.requireNonNull(context.getOpPackageName()), context.getUserId(),
useDefault);
}
/**
@@ -80,9 +87,7 @@ public final class SystemTextClassifier implements TextClassifier {
Objects.requireNonNull(request);
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
request.setUserId(mUserId);
request.setUseDefaultTextClassifier(mUseDefault);
request.setSystemTextClassifierMetadata(mSystemTcMetadata);
final BlockingCallback<TextSelection> callback =
new BlockingCallback<>("textselection");
mManagerService.onSuggestSelection(mSessionId, request, callback);
@@ -105,9 +110,7 @@ public final class SystemTextClassifier implements TextClassifier {
Objects.requireNonNull(request);
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
request.setUserId(mUserId);
request.setUseDefaultTextClassifier(mUseDefault);
request.setSystemTextClassifierMetadata(mSystemTcMetadata);
final BlockingCallback<TextClassification> callback =
new BlockingCallback<>("textclassification");
mManagerService.onClassifyText(mSessionId, request, callback);
@@ -137,9 +140,7 @@ public final class SystemTextClassifier implements TextClassifier {
}
try {
request.setCallingPackageName(mPackageName);
request.setUserId(mUserId);
request.setUseDefaultTextClassifier(mUseDefault);
request.setSystemTextClassifierMetadata(mSystemTcMetadata);
final BlockingCallback<TextLinks> callback =
new BlockingCallback<>("textlinks");
mManagerService.onGenerateLinks(mSessionId, request, callback);
@@ -159,8 +160,7 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
event.setUserId(mUserId);
event.setUseDefaultTextClassifier(mUseDefault);
event.setSystemTextClassifierMetadata(mSystemTcMetadata);
mManagerService.onSelectionEvent(mSessionId, event);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Error reporting selection event.", e);
@@ -173,12 +173,11 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
final TextClassificationContext tcContext = event.getEventContext() == null
? new TextClassificationContext.Builder(mPackageName, WIDGET_TYPE_UNKNOWN)
.build()
: event.getEventContext();
tcContext.setUserId(mUserId);
tcContext.setUseDefaultTextClassifier(mUseDefault);
final TextClassificationContext tcContext =
event.getEventContext() == null ? new TextClassificationContext.Builder(
mSystemTcMetadata.getCallingPackageName(), WIDGET_TYPE_UNKNOWN).build()
: event.getEventContext();
tcContext.setSystemTextClassifierMetadata(mSystemTcMetadata);
event.setEventContext(tcContext);
mManagerService.onTextClassifierEvent(mSessionId, event);
} catch (RemoteException e) {
@@ -192,9 +191,7 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
request.setUserId(mUserId);
request.setUseDefaultTextClassifier(mUseDefault);
request.setSystemTextClassifierMetadata(mSystemTcMetadata);
final BlockingCallback<TextLanguage> callback =
new BlockingCallback<>("textlanguage");
mManagerService.onDetectLanguage(mSessionId, request, callback);
@@ -214,9 +211,7 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
request.setUserId(mUserId);
request.setUseDefaultTextClassifier(mUseDefault);
request.setSystemTextClassifierMetadata(mSystemTcMetadata);
final BlockingCallback<ConversationActions> callback =
new BlockingCallback<>("conversation-actions");
mManagerService.onSuggestConversationActions(mSessionId, request, callback);
@@ -256,10 +251,8 @@ public final class SystemTextClassifier implements TextClassifier {
printWriter.println("SystemTextClassifier:");
printWriter.increaseIndent();
printWriter.printPair("mFallback", mFallback);
printWriter.printPair("mPackageName", mPackageName);
printWriter.printPair("mSessionId", mSessionId);
printWriter.printPair("mUserId", mUserId);
printWriter.printPair("mUseDefault", mUseDefault);
printWriter.printPair("mSystemTcMetadata", mSystemTcMetadata);
printWriter.decreaseIndent();
printWriter.println();
}
@@ -275,7 +268,7 @@ public final class SystemTextClassifier implements TextClassifier {
@NonNull TextClassificationSessionId sessionId) {
mSessionId = Objects.requireNonNull(sessionId);
try {
classificationContext.setUserId(mUserId);
classificationContext.setSystemTextClassifierMetadata(mSystemTcMetadata);
mManagerService.onCreateTextClassificationSession(classificationContext, mSessionId);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Error starting a new classification session.", e);

View File

@@ -0,0 +1,19 @@
/*
* 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.view.textclassifier;
parcelable SystemTextClassifierMetadata;

View File

@@ -0,0 +1,121 @@
/*
* 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.view.textclassifier;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import java.util.Locale;
import java.util.Objects;
/**
* SystemTextClassifier specific information.
* <p>
* This contains information requires for the TextClassificationManagerService to process the
* requests from the application, e.g. user id, calling package name and etc. Centrialize the data
* into this class helps to extend the scalability if we want to add new fields.
* @hide
*/
@VisibleForTesting(visibility = Visibility.PACKAGE)
public final class SystemTextClassifierMetadata implements Parcelable {
/* The name of the package that sent the TC request. */
@NonNull
private final String mCallingPackageName;
/* The id of the user that sent the TC request. */
@UserIdInt
private final int mUserId;
/* Whether to use the default text classifier to handle the request. */
private final boolean mUseDefaultTextClassifier;
public SystemTextClassifierMetadata(@NonNull String packageName, @UserIdInt int userId,
boolean useDefaultTextClassifier) {
Objects.requireNonNull(packageName);
mCallingPackageName = packageName;
mUserId = userId;
mUseDefaultTextClassifier = useDefaultTextClassifier;
}
/**
* Returns the id of the user that sent the TC request.
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Returns the name of the package that sent the TC request.
* This returns {@code null} if no calling package name is set.
*/
@NonNull
public String getCallingPackageName() {
return mCallingPackageName;
}
/**
* Returns whether to use the default text classifier to handle TC request.
*/
public boolean useDefaultTextClassifier() {
return mUseDefaultTextClassifier;
}
@Override
public String toString() {
return String.format(Locale.US,
"SystemTextClassifierMetadata {callingPackageName=%s, userId=%d, "
+ "useDefaultTextClassifier=%b}",
mCallingPackageName, mUserId, mUseDefaultTextClassifier);
}
private static SystemTextClassifierMetadata readFromParcel(Parcel in) {
final String packageName = in.readString();
final int userId = in.readInt();
final boolean useDefaultTextClassifier = in.readBoolean();
return new SystemTextClassifierMetadata(packageName, userId, useDefaultTextClassifier);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mCallingPackageName);
dest.writeInt(mUserId);
dest.writeBoolean(mUseDefaultTextClassifier);
}
public static final @NonNull Creator<SystemTextClassifierMetadata> CREATOR =
new Creator<SystemTextClassifierMetadata>() {
@Override
public SystemTextClassifierMetadata createFromParcel(Parcel in) {
return readFromParcel(in);
}
@Override
public SystemTextClassifierMetadata[] newArray(int size) {
return new SystemTextClassifierMetadata[size];
}
};
}

View File

@@ -21,7 +21,6 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.Context;
@@ -36,7 +35,6 @@ import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.SpannedString;
import android.util.ArrayMap;
import android.view.View.OnClickListener;
@@ -552,10 +550,7 @@ public final class TextClassification implements Parcelable {
@Nullable private final LocaleList mDefaultLocales;
@Nullable private final ZonedDateTime mReferenceTime;
@NonNull private final Bundle mExtras;
@Nullable private String mCallingPackageName;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
private Request(
CharSequence text,
@@ -615,63 +610,34 @@ public final class TextClassification implements Parcelable {
return mReferenceTime;
}
/**
* Sets the name of the package that is sending this request.
* <p>
* For SystemTextClassifier's use.
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setCallingPackageName(@Nullable String callingPackageName) {
mCallingPackageName = callingPackageName;
}
/**
* Returns the name of the package that sent this request.
* This returns {@code null} if no calling package name is set.
*/
@Nullable
public String getCallingPackageName() {
return mCallingPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : null;
}
/**
* Sets the id of the user that sent this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of the user that sent this request.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setSystemTextClassifierMetadata(
@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -773,10 +739,8 @@ public final class TextClassification implements Parcelable {
dest.writeInt(mEndIndex);
dest.writeParcelable(mDefaultLocales, flags);
dest.writeString(mReferenceTime == null ? null : mReferenceTime.toString());
dest.writeString(mCallingPackageName);
dest.writeInt(mUserId);
dest.writeBundle(mExtras);
dest.writeBoolean(mUseDefaultTextClassifier);
dest.writeParcelable(mSystemTcMetadata, flags);
}
private static Request readFromParcel(Parcel in) {
@@ -787,16 +751,12 @@ public final class TextClassification implements Parcelable {
final String referenceTimeString = in.readString();
final ZonedDateTime referenceTime = referenceTimeString == null
? null : ZonedDateTime.parse(referenceTimeString);
final String callingPackageName = in.readString();
final int userId = in.readInt();
final Bundle extras = in.readBundle();
final boolean useDefaultTextClassifier = in.readBoolean();
final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
final Request request = new Request(text, startIndex, endIndex,
defaultLocales, referenceTime, extras);
request.setCallingPackageName(callingPackageName);
request.setUserId(userId);
request.setUseDefaultTextClassifier(useDefaultTextClassifier);
request.setSystemTextClassifierMetadata(systemTcMetadata);
return request;
}

View File

@@ -18,10 +18,8 @@ package android.view.textclassifier;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.view.textclassifier.TextClassifier.WidgetType;
import java.util.Locale;
@@ -33,12 +31,11 @@ import java.util.Objects;
*/
public final class TextClassificationContext implements Parcelable {
private final String mPackageName;
// NOTE: Modify packageName only in the constructor or in setSystemTextClassifierMetadata()
private String mPackageName;
private final String mWidgetType;
@Nullable private final String mWidgetVersion;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
private boolean mUseDefaultTextClassifier;
private SystemTextClassifierMetadata mSystemTcMetadata;
private TextClassificationContext(
String packageName,
@@ -58,42 +55,26 @@ public final class TextClassificationContext implements Parcelable {
}
/**
* Sets the id of this context's user.
* <p>
* Package-private for SystemTextClassifier's use.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* <p><b>NOTE: </b>This will override the value returned in {@link getPackageName()}.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
if (mSystemTcMetadata != null) {
mPackageName = mSystemTcMetadata.getCallingPackageName();
}
}
/**
* Returns the id of this context's user.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -118,8 +99,8 @@ public final class TextClassificationContext implements Parcelable {
@Override
public String toString() {
return String.format(Locale.US, "TextClassificationContext{"
+ "packageName=%s, widgetType=%s, widgetVersion=%s, userId=%d}",
mPackageName, mWidgetType, mWidgetVersion, mUserId);
+ "packageName=%s, widgetType=%s, widgetVersion=%s, systemTcMetadata=%s}",
mPackageName, mWidgetType, mWidgetVersion, mSystemTcMetadata);
}
/**
@@ -176,16 +157,14 @@ public final class TextClassificationContext implements Parcelable {
parcel.writeString(mPackageName);
parcel.writeString(mWidgetType);
parcel.writeString(mWidgetVersion);
parcel.writeInt(mUserId);
parcel.writeBoolean(mUseDefaultTextClassifier);
parcel.writeParcelable(mSystemTcMetadata, flags);
}
private TextClassificationContext(Parcel in) {
mPackageName = in.readString();
mWidgetType = in.readString();
mWidgetVersion = in.readString();
mUserId = in.readInt();
mUseDefaultTextClassifier = in.readBoolean();
mSystemTcMetadata = in.readParcelable(null);
}
public static final @android.annotation.NonNull Parcelable.Creator<TextClassificationContext> CREATOR =

View File

@@ -20,12 +20,10 @@ import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.icu.util.ULocale;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.util.ArrayMap;
import com.android.internal.annotations.VisibleForTesting;
@@ -227,10 +225,7 @@ public final class TextLanguage implements Parcelable {
private final CharSequence mText;
private final Bundle mExtra;
@Nullable private String mCallingPackageName;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
private Request(CharSequence text, Bundle bundle) {
mText = text;
@@ -245,62 +240,34 @@ public final class TextLanguage implements Parcelable {
return mText;
}
/**
* Sets the name of the package that is sending this request.
* Package-private for SystemTextClassifier's use.
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setCallingPackageName(@Nullable String callingPackageName) {
mCallingPackageName = callingPackageName;
}
/**
* Returns the name of the package that sent this request.
* This returns null if no calling package name is set.
*/
@Nullable
public String getCallingPackageName() {
return mCallingPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : null;
}
/**
* Sets the id of the user that sent this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of the user that sent this request.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setSystemTextClassifierMetadata(
@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -321,23 +288,17 @@ public final class TextLanguage implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeCharSequence(mText);
dest.writeString(mCallingPackageName);
dest.writeInt(mUserId);
dest.writeBundle(mExtra);
dest.writeBoolean(mUseDefaultTextClassifier);
dest.writeParcelable(mSystemTcMetadata, flags);
}
private static Request readFromParcel(Parcel in) {
final CharSequence text = in.readCharSequence();
final String callingPackageName = in.readString();
final int userId = in.readInt();
final Bundle extra = in.readBundle();
final boolean useDefaultTextClassifier = in.readBoolean();
final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
final Request request = new Request(text, extra);
request.setCallingPackageName(callingPackageName);
request.setUserId(userId);
request.setUseDefaultTextClassifier(useDefaultTextClassifier);
request.setSystemTextClassifierMetadata(systemTcMetadata);
return request;
}

View File

@@ -20,13 +20,11 @@ import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.Spannable;
import android.text.method.MovementMethod;
import android.text.style.ClickableSpan;
@@ -340,12 +338,9 @@ public final class TextLinks implements Parcelable {
@Nullable private final LocaleList mDefaultLocales;
@Nullable private final EntityConfig mEntityConfig;
private final boolean mLegacyFallback;
@Nullable private String mCallingPackageName;
private final Bundle mExtras;
@Nullable private final ZonedDateTime mReferenceTime;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
private Request(
CharSequence text,
@@ -408,63 +403,34 @@ public final class TextLinks implements Parcelable {
return mReferenceTime;
}
/**
* Sets the name of the package that is sending this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setCallingPackageName(@Nullable String callingPackageName) {
mCallingPackageName = callingPackageName;
}
/**
* Returns the name of the package that sent this request.
* This returns {@code null} if no calling package name is set.
*/
@Nullable
public String getCallingPackageName() {
return mCallingPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : null;
}
/**
* Sets the id of the user that sent this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of the user that sent this request.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setSystemTextClassifierMetadata(
@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -585,30 +551,24 @@ public final class TextLinks implements Parcelable {
dest.writeString(mText.toString());
dest.writeParcelable(mDefaultLocales, flags);
dest.writeParcelable(mEntityConfig, flags);
dest.writeString(mCallingPackageName);
dest.writeInt(mUserId);
dest.writeBundle(mExtras);
dest.writeString(mReferenceTime == null ? null : mReferenceTime.toString());
dest.writeBoolean(mUseDefaultTextClassifier);
dest.writeParcelable(mSystemTcMetadata, flags);
}
private static Request readFromParcel(Parcel in) {
final String text = in.readString();
final LocaleList defaultLocales = in.readParcelable(null);
final EntityConfig entityConfig = in.readParcelable(null);
final String callingPackageName = in.readString();
final int userId = in.readInt();
final Bundle extras = in.readBundle();
final String referenceTimeString = in.readString();
final ZonedDateTime referenceTime = referenceTimeString == null
? null : ZonedDateTime.parse(referenceTimeString);
final boolean useDefaultTextClassifier = in.readBoolean();
final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
final Request request = new Request(text, defaultLocales, entityConfig,
/* legacyFallback= */ true, referenceTime, extras);
request.setCallingPackageName(callingPackageName);
request.setUserId(userId);
request.setUseDefaultTextClassifier(useDefaultTextClassifier);
request.setSystemTextClassifierMetadata(systemTcMetadata);
return request;
}

View File

@@ -20,12 +20,10 @@ import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.SpannedString;
import android.util.ArrayMap;
import android.view.textclassifier.TextClassifier.EntityType;
@@ -213,10 +211,7 @@ public final class TextSelection implements Parcelable {
@Nullable private final LocaleList mDefaultLocales;
private final boolean mDarkLaunchAllowed;
private final Bundle mExtras;
@Nullable private String mCallingPackageName;
@UserIdInt
private int mUserId = UserHandle.USER_NULL;
private boolean mUseDefaultTextClassifier;
@Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
private Request(
CharSequence text,
@@ -277,63 +272,34 @@ public final class TextSelection implements Parcelable {
return mDefaultLocales;
}
/**
* Sets the name of the package that is sending this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setCallingPackageName(@Nullable String callingPackageName) {
mCallingPackageName = callingPackageName;
}
/**
* Returns the name of the package that sent this request.
* This returns {@code null} if no calling package name is set.
*/
@Nullable
public String getCallingPackageName() {
return mCallingPackageName;
return mSystemTcMetadata != null ? mSystemTcMetadata.getCallingPackageName() : null;
}
/**
* Sets the id of the user that sent this request.
* <p>
* Package-private for SystemTextClassifier's use.
* @hide
*/
void setUserId(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Returns the id of the user that sent this request.
* @hide
*/
@UserIdInt
public int getUserId() {
return mUserId;
}
/**
* Sets whether to use the default text classifier to handle this request.
* This will be ignored if it is not the system text classifier to handle this request.
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
void setUseDefaultTextClassifier(boolean useDefaultTextClassifier) {
mUseDefaultTextClassifier = useDefaultTextClassifier;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void setSystemTextClassifierMetadata(
@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
}
/**
* Returns whether to use the default text classifier to handle this request. This
* will be ignored if it is not the system text classifier to handle this request.
* Returns the information about the {@link SystemTextClassifier} that sent this request.
*
* @hide
*/
public boolean getUseDefaultTextClassifier() {
return mUseDefaultTextClassifier;
@Nullable
public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
return mSystemTcMetadata;
}
/**
@@ -438,10 +404,8 @@ public final class TextSelection implements Parcelable {
dest.writeInt(mStartIndex);
dest.writeInt(mEndIndex);
dest.writeParcelable(mDefaultLocales, flags);
dest.writeString(mCallingPackageName);
dest.writeInt(mUserId);
dest.writeBundle(mExtras);
dest.writeBoolean(mUseDefaultTextClassifier);
dest.writeParcelable(mSystemTcMetadata, flags);
}
private static Request readFromParcel(Parcel in) {
@@ -449,16 +413,12 @@ public final class TextSelection implements Parcelable {
final int startIndex = in.readInt();
final int endIndex = in.readInt();
final LocaleList defaultLocales = in.readParcelable(null);
final String callingPackageName = in.readString();
final int userId = in.readInt();
final Bundle extras = in.readBundle();
final boolean systemTextClassifierType = in.readBoolean();
final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
final Request request = new Request(text, startIndex, endIndex, defaultLocales,
/* darkLaunchAllowed= */ false, extras);
request.setCallingPackageName(callingPackageName);
request.setUserId(userId);
request.setUseDefaultTextClassifier(systemTextClassifierType);
request.setSystemTextClassifierMetadata(systemTcMetadata);
return request;
}

View File

@@ -0,0 +1,61 @@
/*
* 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.view.textclassifier;
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.assertThrows;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SystemTextClassifierMetadataTest {
@Test
public void testInvalidPackageNameThrowsException() {
assertThrows(NullPointerException.class,
() -> new SystemTextClassifierMetadata(/* packageName= */ null, /* userId= */
1, /* useDefaultTextClassifier= */ false));
}
@Test
public void testParcel() {
SystemTextClassifierMetadata sysTcMetadata = new SystemTextClassifierMetadata(
"package", /* userId= */ 1, /* useDefaultTextClassifier= */ false);
Parcel p = Parcel.obtain();
sysTcMetadata.writeToParcel(p, 0);
p.setDataPosition(0);
SystemTextClassifierMetadata targetSysTcMetadata =
SystemTextClassifierMetadata.CREATOR.createFromParcel(p);
assertThat(targetSysTcMetadata.getUserId()).isEqualTo(sysTcMetadata.getUserId());
assertThat(targetSysTcMetadata.getCallingPackageName()).isEqualTo(
sysTcMetadata.getCallingPackageName());
assertThat(targetSysTcMetadata.useDefaultTextClassifier()).isEqualTo(
sysTcMetadata.useDefaultTextClassifier());
}
}

View File

@@ -17,6 +17,7 @@
package android.view.textclassifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -199,7 +200,9 @@ public class TextClassificationTest {
.setReferenceTime(referenceTime)
.setExtras(BUNDLE)
.build();
reference.setCallingPackageName(packageName);
final SystemTextClassifierMetadata systemTcMetadata =
new SystemTextClassifierMetadata(packageName, 1, false);
reference.setSystemTextClassifierMetadata(systemTcMetadata);
// Parcel and unparcel.
final Parcel parcel = Parcel.obtain();
@@ -216,5 +219,11 @@ public class TextClassificationTest {
assertEquals(referenceTime, result.getReferenceTime());
assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
assertEquals(packageName, result.getCallingPackageName());
final SystemTextClassifierMetadata resultSystemTcMetadata =
result.getSystemTextClassifierMetadata();
assertNotNull(resultSystemTcMetadata);
assertEquals(packageName, resultSystemTcMetadata.getCallingPackageName());
assertEquals(1, resultSystemTcMetadata.getUserId());
assertFalse(resultSystemTcMetadata.useDefaultTextClassifier());
}
}

View File

@@ -17,6 +17,8 @@
package android.view.textclassifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import android.icu.util.ULocale;
import android.os.Bundle;
@@ -75,7 +77,9 @@ public final class TextLanguageTest {
final TextLanguage.Request reference = new TextLanguage.Request.Builder(text)
.setExtras(bundle)
.build();
reference.setCallingPackageName(packageName);
final SystemTextClassifierMetadata systemTcMetadata =
new SystemTextClassifierMetadata(packageName, 1, false);
reference.setSystemTextClassifierMetadata(systemTcMetadata);
final Parcel parcel = Parcel.obtain();
reference.writeToParcel(parcel, 0);
@@ -85,5 +89,11 @@ public final class TextLanguageTest {
assertEquals(text, result.getText());
assertEquals("bundle", result.getExtras().getString(bundleKey));
assertEquals(packageName, result.getCallingPackageName());
final SystemTextClassifierMetadata resultSystemTcMetadata =
result.getSystemTextClassifierMetadata();
assertNotNull(resultSystemTcMetadata);
assertEquals(packageName, resultSystemTcMetadata.getCallingPackageName());
assertEquals(1, resultSystemTcMetadata.getUserId());
assertFalse(resultSystemTcMetadata.useDefaultTextClassifier());
}
}

View File

@@ -17,6 +17,8 @@
package android.view.textclassifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import android.os.Bundle;
import android.os.LocaleList;
@@ -115,7 +117,9 @@ public class TextLinksTest {
.setExtras(BUNDLE)
.setReferenceTime(referenceTime)
.build();
reference.setCallingPackageName(packageName);
final SystemTextClassifierMetadata systemTcMetadata =
new SystemTextClassifierMetadata(packageName, 1, false);
reference.setSystemTextClassifierMetadata(systemTcMetadata);
// Parcel and unparcel.
final Parcel parcel = Parcel.obtain();
@@ -132,5 +136,11 @@ public class TextLinksTest {
assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
assertEquals(packageName, result.getCallingPackageName());
assertEquals(referenceTime, result.getReferenceTime());
final SystemTextClassifierMetadata resultSystemTcMetadata =
result.getSystemTextClassifierMetadata();
assertNotNull(resultSystemTcMetadata);
assertEquals(packageName, resultSystemTcMetadata.getCallingPackageName());
assertEquals(1, resultSystemTcMetadata.getUserId());
assertFalse(resultSystemTcMetadata.useDefaultTextClassifier());
}
}

View File

@@ -17,6 +17,8 @@
package android.view.textclassifier;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import android.os.Bundle;
import android.os.LocaleList;
@@ -82,7 +84,9 @@ public class TextSelectionTest {
.setDefaultLocales(new LocaleList(Locale.US, Locale.GERMANY))
.setExtras(BUNDLE)
.build();
reference.setCallingPackageName(packageName);
final SystemTextClassifierMetadata systemTcMetadata =
new SystemTextClassifierMetadata(packageName, 1, false);
reference.setSystemTextClassifierMetadata(systemTcMetadata);
// Parcel and unparcel.
final Parcel parcel = Parcel.obtain();
@@ -96,5 +100,11 @@ public class TextSelectionTest {
assertEquals("en-US,de-DE", result.getDefaultLocales().toLanguageTags());
assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
assertEquals(packageName, result.getCallingPackageName());
final SystemTextClassifierMetadata resultSystemTcMetadata =
result.getSystemTextClassifierMetadata();
assertNotNull(resultSystemTcMetadata);
assertEquals(packageName, resultSystemTcMetadata.getCallingPackageName());
assertEquals(1, resultSystemTcMetadata.getUserId());
assertFalse(resultSystemTcMetadata.useDefaultTextClassifier());
}
}

View File

@@ -41,6 +41,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.SystemTextClassifierMetadata;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationConstants;
import android.view.textclassifier.TextClassificationContext;
@@ -179,12 +180,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
TextSelection.Request request, ITextClassifierCallback callback)
throws RemoteException {
Objects.requireNonNull(request);
Objects.requireNonNull(request.getSystemTextClassifierMetadata());
handleRequest(
request.getUserId(),
request.getCallingPackageName(),
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
request.getUseDefaultTextClassifier(),
service -> service.onSuggestSelection(sessionId, request, callback),
"onSuggestSelection",
callback);
@@ -196,12 +197,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
TextClassification.Request request, ITextClassifierCallback callback)
throws RemoteException {
Objects.requireNonNull(request);
Objects.requireNonNull(request.getSystemTextClassifierMetadata());
handleRequest(
request.getUserId(),
request.getCallingPackageName(),
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
request.getUseDefaultTextClassifier(),
service -> service.onClassifyText(sessionId, request, callback),
"onClassifyText",
callback);
@@ -213,12 +214,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
TextLinks.Request request, ITextClassifierCallback callback)
throws RemoteException {
Objects.requireNonNull(request);
Objects.requireNonNull(request.getSystemTextClassifierMetadata());
handleRequest(
request.getUserId(),
request.getCallingPackageName(),
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
request.getUseDefaultTextClassifier(),
service -> service.onGenerateLinks(sessionId, request, callback),
"onGenerateLinks",
callback);
@@ -229,12 +230,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
@Nullable TextClassificationSessionId sessionId, SelectionEvent event)
throws RemoteException {
Objects.requireNonNull(event);
Objects.requireNonNull(event.getSystemTextClassifierMetadata());
handleRequest(
event.getUserId(),
/* callingPackageName= */ null,
event.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ false,
/* attemptToBind= */ false,
event.getUseDefaultTextClassifier(),
service -> service.onSelectionEvent(sessionId, event),
"onSelectionEvent",
NO_OP_CALLBACK);
@@ -246,18 +247,14 @@ public final class TextClassificationManagerService extends ITextClassifierServi
TextClassifierEvent event) throws RemoteException {
Objects.requireNonNull(event);
final int userId = event.getEventContext() == null
? UserHandle.getCallingUserId()
: event.getEventContext().getUserId();
final boolean useDefaultTextClassifier =
event.getEventContext() != null
? event.getEventContext().getUseDefaultTextClassifier()
: true;
final TextClassificationContext eventContext = event.getEventContext();
final SystemTextClassifierMetadata systemTcMetadata =
eventContext != null ? eventContext.getSystemTextClassifierMetadata() : null;
handleRequest(
userId,
/* callingPackageName= */ null,
systemTcMetadata,
/* verifyCallingPackage= */ false,
/* attemptToBind= */ false,
useDefaultTextClassifier,
service -> service.onTextClassifierEvent(sessionId, event),
"onTextClassifierEvent",
NO_OP_CALLBACK);
@@ -269,12 +266,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
TextLanguage.Request request,
ITextClassifierCallback callback) throws RemoteException {
Objects.requireNonNull(request);
Objects.requireNonNull(request.getSystemTextClassifierMetadata());
handleRequest(
request.getUserId(),
request.getCallingPackageName(),
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
request.getUseDefaultTextClassifier(),
service -> service.onDetectLanguage(sessionId, request, callback),
"onDetectLanguage",
callback);
@@ -286,12 +283,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
ConversationActions.Request request,
ITextClassifierCallback callback) throws RemoteException {
Objects.requireNonNull(request);
Objects.requireNonNull(request.getSystemTextClassifierMetadata());
handleRequest(
request.getUserId(),
request.getCallingPackageName(),
request.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ true,
request.getUseDefaultTextClassifier(),
service -> service.onSuggestConversationActions(sessionId, request, callback),
"onSuggestConversationActions",
callback);
@@ -303,13 +300,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi
throws RemoteException {
Objects.requireNonNull(sessionId);
Objects.requireNonNull(classificationContext);
Objects.requireNonNull(classificationContext.getSystemTextClassifierMetadata());
final int userId = classificationContext.getUserId();
handleRequest(
userId,
classificationContext.getPackageName(),
classificationContext.getSystemTextClassifierMetadata(),
/* verifyCallingPackage= */ true,
/* attemptToBind= */ false,
classificationContext.getUseDefaultTextClassifier(),
service -> {
service.onCreateTextClassificationSession(classificationContext, sessionId);
mSessionCache.put(sessionId, classificationContext);
@@ -333,11 +329,13 @@ public final class TextClassificationManagerService extends ITextClassifierServi
textClassificationContext != null
? textClassificationContext.useDefaultTextClassifier
: true;
final SystemTextClassifierMetadata sysTcMetadata = new SystemTextClassifierMetadata(
"", userId, useDefaultTextClassifier);
handleRequest(
userId,
/* callingPackageName= */ null,
sysTcMetadata,
/* verifyCallingPackage= */ false,
/* attemptToBind= */ false,
useDefaultTextClassifier,
service -> {
service.onDestroyTextClassificationSession(sessionId);
mSessionCache.remove(sessionId);
@@ -412,10 +410,9 @@ public final class TextClassificationManagerService extends ITextClassifierServi
}
private void handleRequest(
@UserIdInt int userId,
@Nullable String callingPackageName,
@Nullable SystemTextClassifierMetadata sysTcMetadata,
boolean verifyCallingPackage,
boolean attemptToBind,
boolean useDefaultTextClassifier,
@NonNull ThrowingConsumer<ITextClassifierService> textClassifierServiceConsumer,
@NonNull String methodName,
@NonNull ITextClassifierCallback callback) throws RemoteException {
@@ -423,8 +420,17 @@ public final class TextClassificationManagerService extends ITextClassifierServi
Objects.requireNonNull(methodName);
Objects.requireNonNull(callback);
final int userId =
sysTcMetadata == null ? UserHandle.getCallingUserId() : sysTcMetadata.getUserId();
final String callingPackageName =
sysTcMetadata == null ? null : sysTcMetadata.getCallingPackageName();
final boolean useDefaultTextClassifier =
sysTcMetadata == null ? true : sysTcMetadata.useDefaultTextClassifier();
try {
validateCallingPackage(callingPackageName);
if (verifyCallingPackage) {
validateCallingPackage(callingPackageName);
}
validateUser(userId);
} catch (Exception e) {
throw new RemoteException("Invalid request: " + e.getMessage(), e,
@@ -636,8 +642,10 @@ public final class TextClassificationManagerService extends ITextClassifierServi
public final boolean useDefaultTextClassifier;
StrippedTextClassificationContext(TextClassificationContext textClassificationContext) {
userId = textClassificationContext.getUserId();
useDefaultTextClassifier = textClassificationContext.getUseDefaultTextClassifier();
SystemTextClassifierMetadata sysTcMetadata =
textClassificationContext.getSystemTextClassifierMetadata();
userId = sysTcMetadata.getUserId();
useDefaultTextClassifier = sysTcMetadata.useDefaultTextClassifier();
}
}