Merge "Add a way to read the last AutofillSelection." into oc-dev
am: 42775f2a89
Change-Id: I6be640dc4bf6ceba6889c59a4e464540f3834e6e
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user