Merge "Add a way to read the last AutofillSelection." into oc-dev
am: 42775f2a89
Change-Id: I6be640dc4bf6ceba6889c59a4e464540f3834e6e
This commit is contained in:
@@ -37030,6 +37030,7 @@ package android.service.autofill {
|
||||
public abstract class AutofillService extends android.app.Service {
|
||||
ctor public AutofillService();
|
||||
method public final deprecated void disableSelf();
|
||||
method public final android.service.autofill.FillEventHistory getFillEventHistory();
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
@@ -37052,6 +37053,7 @@ package android.service.autofill {
|
||||
ctor public Dataset.Builder();
|
||||
method public android.service.autofill.Dataset build();
|
||||
method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
|
||||
method public android.service.autofill.Dataset.Builder setId(java.lang.String);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
|
||||
}
|
||||
@@ -37069,6 +37071,23 @@ package android.service.autofill {
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillEventHistory implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
|
||||
}
|
||||
|
||||
public static final class FillEventHistory.Event {
|
||||
method public java.lang.String getDatasetId();
|
||||
method public int getType();
|
||||
field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
|
||||
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
|
||||
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
|
||||
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
|
||||
@@ -40142,6 +40142,7 @@ package android.service.autofill {
|
||||
public abstract class AutofillService extends android.app.Service {
|
||||
ctor public AutofillService();
|
||||
method public final deprecated void disableSelf();
|
||||
method public final android.service.autofill.FillEventHistory getFillEventHistory();
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
@@ -40164,6 +40165,7 @@ package android.service.autofill {
|
||||
ctor public Dataset.Builder();
|
||||
method public android.service.autofill.Dataset build();
|
||||
method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
|
||||
method public android.service.autofill.Dataset.Builder setId(java.lang.String);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
|
||||
}
|
||||
@@ -40181,6 +40183,23 @@ package android.service.autofill {
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillEventHistory implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
|
||||
}
|
||||
|
||||
public static final class FillEventHistory.Event {
|
||||
method public java.lang.String getDatasetId();
|
||||
method public int getType();
|
||||
field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
|
||||
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
|
||||
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
|
||||
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
|
||||
@@ -37183,6 +37183,7 @@ package android.service.autofill {
|
||||
public abstract class AutofillService extends android.app.Service {
|
||||
ctor public AutofillService();
|
||||
method public final deprecated void disableSelf();
|
||||
method public final android.service.autofill.FillEventHistory getFillEventHistory();
|
||||
method public final android.os.IBinder onBind(android.content.Intent);
|
||||
method public void onConnected();
|
||||
method public void onDisconnected();
|
||||
@@ -37205,6 +37206,7 @@ package android.service.autofill {
|
||||
ctor public Dataset.Builder();
|
||||
method public android.service.autofill.Dataset build();
|
||||
method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
|
||||
method public android.service.autofill.Dataset.Builder setId(java.lang.String);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
|
||||
method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
|
||||
}
|
||||
@@ -37222,6 +37224,23 @@ package android.service.autofill {
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
|
||||
}
|
||||
|
||||
public final class FillEventHistory implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
|
||||
}
|
||||
|
||||
public static final class FillEventHistory.Event {
|
||||
method public java.lang.String getDatasetId();
|
||||
method public int getType();
|
||||
field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
|
||||
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
|
||||
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
|
||||
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
|
||||
}
|
||||
|
||||
public final class FillRequest implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getClientState();
|
||||
|
||||
@@ -285,4 +285,22 @@ public abstract class AutofillService extends Service {
|
||||
// TODO(b/33197203): Remove when GCore has migrated off this API
|
||||
getSystemService(AutofillManager.class).disableOwnedAutofillServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link FillEventHistory.Event events} since the last {@link FillResponse} was
|
||||
* returned.
|
||||
*
|
||||
* <p>The history is not persisted over reboots.
|
||||
*
|
||||
* @return The history or {@code null} if there are not events.
|
||||
*/
|
||||
@Nullable public final FillEventHistory getFillEventHistory() {
|
||||
AutofillManager afm = getSystemService(AutofillManager.class);
|
||||
|
||||
if (afm == null) {
|
||||
return null;
|
||||
} else {
|
||||
return afm.getFillEventHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.IntentSender;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
import android.widget.RemoteViews;
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -50,6 +51,7 @@ public final class Dataset implements Parcelable {
|
||||
private final ArrayList<RemoteViews> mFieldPresentations;
|
||||
private final RemoteViews mPresentation;
|
||||
private final IntentSender mAuthentication;
|
||||
@Nullable String mId;
|
||||
|
||||
private Dataset(Builder builder) {
|
||||
mFieldIds = builder.mFieldIds;
|
||||
@@ -57,6 +59,7 @@ public final class Dataset implements Parcelable {
|
||||
mFieldPresentations = builder.mFieldPresentations;
|
||||
mPresentation = builder.mPresentation;
|
||||
mAuthentication = builder.mAuthentication;
|
||||
mId = builder.mId;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -89,7 +92,7 @@ public final class Dataset implements Parcelable {
|
||||
public String toString() {
|
||||
if (!DEBUG) return super.toString();
|
||||
|
||||
return new StringBuilder("Dataset [")
|
||||
return new StringBuilder("Dataset " + mId + " [")
|
||||
.append("fieldIds=").append(mFieldIds)
|
||||
.append(", fieldValues=").append(mFieldValues)
|
||||
.append(", fieldPresentations=")
|
||||
@@ -99,6 +102,17 @@ public final class Dataset implements Parcelable {
|
||||
.append(']').toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this dataset.
|
||||
*
|
||||
* @return The id of this dataset or {@code null} if not set
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public String getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for {@link Dataset} objects. You must to provide at least
|
||||
* one value for a field or set an authentication intent.
|
||||
@@ -110,6 +124,7 @@ public final class Dataset implements Parcelable {
|
||||
private RemoteViews mPresentation;
|
||||
private IntentSender mAuthentication;
|
||||
private boolean mDestroyed;
|
||||
@Nullable private String mId;
|
||||
|
||||
/**
|
||||
* Creates a new builder.
|
||||
@@ -172,6 +187,25 @@ public final class Dataset implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id for the dataset.
|
||||
*
|
||||
* <p>The id of the last selected dataset can be read from
|
||||
* {@link AutofillService#getFillEventHistory()}. If the id is not set it will not be clear
|
||||
* if a dataset was selected as {@link AutofillService#getFillEventHistory()} uses
|
||||
* {@code null} to indicate that no dataset was selected.
|
||||
*
|
||||
* @param id id for this dataset or {@code null} to unset.
|
||||
|
||||
* @return This builder.
|
||||
*/
|
||||
public @NonNull Builder setId(@Nullable String id) {
|
||||
throwIfDestroyed();
|
||||
|
||||
mId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field.
|
||||
*
|
||||
@@ -269,6 +303,7 @@ public final class Dataset implements Parcelable {
|
||||
parcel.writeTypedArrayList(mFieldValues, flags);
|
||||
parcel.writeParcelableList(mFieldPresentations, flags);
|
||||
parcel.writeParcelable(mAuthentication, flags);
|
||||
parcel.writeString(mId);
|
||||
}
|
||||
|
||||
public static final Creator<Dataset> CREATOR = new Creator<Dataset>() {
|
||||
@@ -295,6 +330,7 @@ public final class Dataset implements Parcelable {
|
||||
builder.setValueAndPresentation(id, value, fieldPresentation);
|
||||
}
|
||||
builder.setAuthentication(parcel.readParcelable(null));
|
||||
builder.setId(parcel.readString());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
19
core/java/android/service/autofill/FillEventHistory.aidl
Normal file
19
core/java/android/service/autofill/FillEventHistory.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
parcelable FillEventHistory;
|
||||
208
core/java/android/service/autofill/FillEventHistory.java
Normal file
208
core/java/android/service/autofill/FillEventHistory.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package android.service.autofill;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.IntentSender;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describes what happened after the latest call to {@link FillCallback#onSuccess(FillResponse)}.
|
||||
*/
|
||||
public final class FillEventHistory implements Parcelable {
|
||||
/**
|
||||
* Not in parcel. The UID of the {@link AutofillService} that created the {@link FillResponse}.
|
||||
*/
|
||||
private final int mServiceUid;
|
||||
|
||||
@Nullable private final Bundle mClientState;
|
||||
@Nullable List<Event> mEvents;
|
||||
|
||||
/**
|
||||
* Gets the UID of the {@link AutofillService} that created the {@link FillResponse}.
|
||||
*
|
||||
* @return The UID of the {@link AutofillService}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public int getServiceUid() {
|
||||
return mServiceUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the client state of the {@link FillResponse}.
|
||||
*
|
||||
* @return The client state set by the last {@link FillResponse}
|
||||
*/
|
||||
@Nullable public Bundle getClientState() {
|
||||
return mClientState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the events occurred after the latest call to
|
||||
* {@link FillCallback#onSuccess(FillResponse)}.
|
||||
*
|
||||
* @return The list of events or {@code null} if non occurred.
|
||||
*/
|
||||
@Nullable public List<Event> getEvents() {
|
||||
return mEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void addEvent(Event event) {
|
||||
if (mEvents == null) {
|
||||
mEvents = new ArrayList<>(1);
|
||||
}
|
||||
mEvents.add(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public FillEventHistory(int serviceUid, @Nullable Bundle clientState) {
|
||||
mClientState = clientState;
|
||||
mServiceUid = serviceUid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeBundle(mClientState);
|
||||
|
||||
if (mEvents == null) {
|
||||
dest.writeInt(0);
|
||||
} else {
|
||||
dest.writeInt(mEvents.size());
|
||||
|
||||
int numEvents = mEvents.size();
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
Event event = mEvents.get(i);
|
||||
dest.writeInt(event.getType());
|
||||
dest.writeString(event.getDatasetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of an event that occured after the latest call to
|
||||
* {@link FillCallback#onSuccess(FillResponse)}.
|
||||
*/
|
||||
public static final class Event {
|
||||
/**
|
||||
* A dataset was selected. The dataset selected can be read from {@link #getDatasetId()}.
|
||||
*/
|
||||
public static final int TYPE_DATASET_SELECTED = 0;
|
||||
|
||||
/**
|
||||
* A {@link Dataset.Builder#setAuthentication(IntentSender) dataset authentication} was
|
||||
* selected. The dataset authenticated can be read from {@link #getDatasetId()}.
|
||||
*/
|
||||
public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1;
|
||||
|
||||
/**
|
||||
* A {@link FillResponse.Builder#setAuthentication(AutofillId[], IntentSender, RemoteViews)
|
||||
* fill response authentication} was selected.
|
||||
*/
|
||||
public static final int TYPE_AUTHENTICATION_SELECTED = 2;
|
||||
|
||||
/** A save UI was shown. */
|
||||
public static final int TYPE_SAVE_SHOWN = 3;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(
|
||||
value = {TYPE_DATASET_SELECTED,
|
||||
TYPE_DATASET_AUTHENTICATION_SELECTED,
|
||||
TYPE_AUTHENTICATION_SELECTED,
|
||||
TYPE_SAVE_SHOWN})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface EventIds{}
|
||||
|
||||
@EventIds private final int mEventType;
|
||||
@Nullable private final String mDatasetId;
|
||||
|
||||
/**
|
||||
* Returns the type of the event.
|
||||
*
|
||||
* @return The type of the event
|
||||
*/
|
||||
public int getType() {
|
||||
return mEventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of dataset the id was on.
|
||||
*
|
||||
* @return The id of dataset, or {@code null} the event is not associated with a dataset.
|
||||
*/
|
||||
@Nullable public String getDatasetId() {
|
||||
return mDatasetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new event.
|
||||
*
|
||||
* @param eventType The type of the event
|
||||
* @param datasetId The dataset the event was on, or {@code null} if the event was on the
|
||||
* whole response.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Event(int eventType, String datasetId) {
|
||||
mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_SAVE_SHOWN,
|
||||
"eventType");
|
||||
mDatasetId = datasetId;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<FillEventHistory> CREATOR =
|
||||
new Parcelable.Creator<FillEventHistory>() {
|
||||
@Override
|
||||
public FillEventHistory createFromParcel(Parcel parcel) {
|
||||
FillEventHistory selection = new FillEventHistory(0, parcel.readBundle());
|
||||
|
||||
int numEvents = parcel.readInt();
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
selection.addEvent(new Event(parcel.readInt(), parcel.readString()));
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FillEventHistory[] newArray(int size) {
|
||||
return new FillEventHistory[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -31,6 +31,8 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
@@ -333,6 +335,20 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should always be called from {@link AutofillService#getFillEventHistory()}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Nullable public FillEventHistory getFillEventHistory() {
|
||||
try {
|
||||
return mService.getFillEventHistory();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly requests a new autofill context.
|
||||
*
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.view.autofill;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillValue;
|
||||
import android.view.autofill.IAutoFillManagerClient;
|
||||
@@ -33,6 +34,7 @@ interface IAutoFillManager {
|
||||
int startSession(IBinder activityToken, IBinder windowToken, in IBinder appCallback,
|
||||
in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
|
||||
boolean hasCallback, int flags, String packageName);
|
||||
FillEventHistory getFillEventHistory();
|
||||
boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
|
||||
void setWindow(int sessionId, in IBinder windowToken);
|
||||
void updateSession(int sessionId, in AutofillId id, in Rect bounds,
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.provider.Settings;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
import android.util.LocalLog;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -397,6 +398,21 @@ public final class AutofillManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FillEventHistory getFillEventHistory() throws RemoteException {
|
||||
UserHandle user = getCallingUserHandle();
|
||||
int uid = getCallingUid();
|
||||
|
||||
synchronized (mLock) {
|
||||
AutofillManagerServiceImpl service = peekServiceForUserLocked(user.getIdentifier());
|
||||
if (service != null) {
|
||||
return service.getFillEventHistory(uid);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreSession(int sessionId, IBinder activityToken, IBinder appCallback)
|
||||
throws RemoteException {
|
||||
|
||||
@@ -48,7 +48,9 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.autofill.AutofillService;
|
||||
import android.service.autofill.AutofillServiceInfo;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
import android.service.autofill.FillRequest;
|
||||
import android.service.autofill.FillResponse;
|
||||
import android.service.autofill.IAutoFillService;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LocalLog;
|
||||
@@ -122,6 +124,10 @@ final class AutofillManagerServiceImpl {
|
||||
@GuardedBy("mLock")
|
||||
private final SparseArray<Session> mSessions = new SparseArray<>();
|
||||
|
||||
/** The last selection */
|
||||
@GuardedBy("mLock")
|
||||
private FillEventHistory mEventHistory;
|
||||
|
||||
/**
|
||||
* Receiver of assist data from the app's {@link Activity}.
|
||||
*/
|
||||
@@ -500,6 +506,72 @@ final class AutofillManagerServiceImpl {
|
||||
return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the last fill selection after an autofill service returned a new
|
||||
* {@link FillResponse}.
|
||||
*/
|
||||
void setLastResponse(int serviceUid, @NonNull FillResponse response) {
|
||||
synchronized (mLock) {
|
||||
mEventHistory = new FillEventHistory(serviceUid, response.getClientState());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last fill selection when an authentication was selected.
|
||||
*/
|
||||
void setAuthenticationSelected() {
|
||||
synchronized (mLock) {
|
||||
mEventHistory.addEvent(
|
||||
new FillEventHistory.Event(FillEventHistory.Event.TYPE_AUTHENTICATION_SELECTED, null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last fill selection when an dataset authentication was selected.
|
||||
*/
|
||||
void setDatasetAuthenticationSelected(@Nullable String selectedDataset) {
|
||||
synchronized (mLock) {
|
||||
mEventHistory.addEvent(new FillEventHistory.Event(
|
||||
FillEventHistory.Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last fill selection when an save Ui is shown.
|
||||
*/
|
||||
void setSaveShown() {
|
||||
synchronized (mLock) {
|
||||
mEventHistory.addEvent(new FillEventHistory.Event(FillEventHistory.Event.TYPE_SAVE_SHOWN, null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the last fill response when a dataset was selected.
|
||||
*/
|
||||
void setDatasetSelected(@Nullable String selectedDataset) {
|
||||
synchronized (mLock) {
|
||||
mEventHistory.addEvent(
|
||||
new FillEventHistory.Event(FillEventHistory.Event.TYPE_DATASET_SELECTED, selectedDataset));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fill event history.
|
||||
*
|
||||
* @param callingUid The calling uid
|
||||
*
|
||||
* @return The history or {@code null} if there is none.
|
||||
*/
|
||||
FillEventHistory getFillEventHistory(int callingUid) {
|
||||
synchronized (mLock) {
|
||||
if (mEventHistory != null && mEventHistory.getServiceUid() == callingUid) {
|
||||
return mEventHistory;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void dumpLocked(String prefix, PrintWriter pw) {
|
||||
final String prefix2 = prefix + " ";
|
||||
|
||||
@@ -528,6 +600,20 @@ final class AutofillManagerServiceImpl {
|
||||
mSessions.valueAt(i).dumpLocked(prefix2, pw);
|
||||
}
|
||||
}
|
||||
|
||||
if (mEventHistory == null || mEventHistory.getEvents().size() == 0) {
|
||||
pw.print(prefix); pw.println("No event on last fill response");
|
||||
} else {
|
||||
pw.print(prefix); pw.println("Events of last fill response:");
|
||||
pw.print(prefix);
|
||||
|
||||
int numEvents = mEventHistory.getEvents().size();
|
||||
for (int i = 0; i < numEvents; i++) {
|
||||
FillEventHistory.Event event = mEventHistory.getEvents().get(i);
|
||||
pw.println(" " + i + ": eventType=" + event.getType() + " datasetId="
|
||||
+ event.getDatasetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destroySessionsLocked() {
|
||||
|
||||
@@ -87,7 +87,7 @@ final class RemoteFillService implements DeathRecipient {
|
||||
private PendingRequest mPendingRequest;
|
||||
|
||||
public interface FillServiceCallbacks {
|
||||
void onFillRequestSuccess(@Nullable FillResponse response,
|
||||
void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
|
||||
@NonNull String servicePackageName, int requestId);
|
||||
void onFillRequestFailure(@Nullable CharSequence message,
|
||||
@NonNull String servicePackageName);
|
||||
@@ -252,11 +252,11 @@ final class RemoteFillService implements DeathRecipient {
|
||||
}
|
||||
|
||||
private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
|
||||
FillResponse response, int requestId) {
|
||||
int callingUid, FillResponse response, int requestId) {
|
||||
mHandler.getHandler().post(() -> {
|
||||
if (handleResponseCallbackCommon(pendingRequest)) {
|
||||
mCallbacks.onFillRequestSuccess(response, mComponentName.getPackageName(),
|
||||
requestId);
|
||||
mCallbacks.onFillRequestSuccess(response, callingUid,
|
||||
mComponentName.getPackageName(), requestId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -424,7 +424,7 @@ final class RemoteFillService implements DeathRecipient {
|
||||
RemoteFillService remoteService = mWeakService.get();
|
||||
if (remoteService != null) {
|
||||
remoteService.dispatchOnFillRequestSuccess(
|
||||
PendingFillRequest.this, response, requestId);
|
||||
PendingFillRequest.this, getCallingUid(), response, requestId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
// FillServiceCallbacks
|
||||
@Override
|
||||
public void onFillRequestSuccess(@Nullable FillResponse response,
|
||||
public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
|
||||
@NonNull String servicePackageName, int requestId) {
|
||||
if (response == null) {
|
||||
if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
|
||||
@@ -241,6 +241,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
return;
|
||||
}
|
||||
|
||||
mService.setLastResponse(serviceUid, response);
|
||||
|
||||
if ((response.getDatasets() == null || response.getDatasets().isEmpty())
|
||||
&& response.getAuthentication() == null) {
|
||||
// Response is "empty" from an UI point of view, need to notify client.
|
||||
@@ -314,6 +316,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
synchronized (mLock) {
|
||||
fillInIntent = createAuthFillInIntent(mStructure, extras);
|
||||
}
|
||||
|
||||
mService.setAuthenticationSelected();
|
||||
|
||||
mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
|
||||
}
|
||||
|
||||
@@ -542,6 +547,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
}
|
||||
if (atLeastOneChanged) {
|
||||
mService.setSaveShown();
|
||||
getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName);
|
||||
return false;
|
||||
}
|
||||
@@ -882,12 +888,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
synchronized (mLock) {
|
||||
// Autofill it directly...
|
||||
if (dataset.getAuthentication() == null) {
|
||||
mService.setDatasetSelected(dataset.getId());
|
||||
|
||||
autoFillApp(dataset);
|
||||
return;
|
||||
}
|
||||
|
||||
// ...or handle authentication.
|
||||
// TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
|
||||
mService.setDatasetAuthenticationSelected(dataset.getId());
|
||||
mDatasetWaitingAuth = dataset;
|
||||
setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
|
||||
final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
|
||||
|
||||
Reference in New Issue
Block a user