FillEventHistory.java revision d013bcea9713d178627cc1d3e8a0f291ccbcd293
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.service.autofill; 18 19import android.annotation.IntDef; 20import android.annotation.Nullable; 21import android.content.IntentSender; 22import android.os.Bundle; 23import android.os.Parcel; 24import android.os.Parcelable; 25import android.view.autofill.AutofillId; 26import android.widget.RemoteViews; 27 28import com.android.internal.util.Preconditions; 29 30import java.lang.annotation.Retention; 31import java.lang.annotation.RetentionPolicy; 32import java.util.ArrayList; 33import java.util.List; 34 35/** 36 * Describes what happened after the last 37 * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} 38 * call. 39 * 40 * <p>This history is typically used to keep track of previous user actions to optimize further 41 * requests. For example, the service might return email addresses in alphabetical order by 42 * default, but change that order based on the address the user picked on previous requests. 43 * 44 * <p>The history is not persisted over reboots, and it's cleared every time the service 45 * replies to a 46 * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} 47 * by calling {@link FillCallback#onSuccess(FillResponse)} or 48 * {@link FillCallback#onFailure(CharSequence)} (if the service doesn't call any of these methods, 49 * the history will clear out after some pre-defined time). 50 */ 51public final class FillEventHistory implements Parcelable { 52 /** 53 * Not in parcel. The UID of the {@link AutofillService} that created the {@link FillResponse}. 54 */ 55 private final int mServiceUid; 56 57 /** 58 * Not in parcel. The ID of the autofill session that created the {@link FillResponse}. 59 */ 60 private final int mSessionId; 61 62 @Nullable private final Bundle mClientState; 63 @Nullable List<Event> mEvents; 64 65 /** 66 * Gets the UID of the {@link AutofillService} that created the {@link FillResponse}. 67 * 68 * @return The UID of the {@link AutofillService} 69 * 70 * @hide 71 */ 72 public int getServiceUid() { 73 return mServiceUid; 74 } 75 76 /** @hide */ 77 public int getSessionId() { 78 return mSessionId; 79 } 80 81 /** 82 * Returns the client state set in the previous {@link FillResponse}. 83 * 84 * <p><b>NOTE: </b>the state is associated with the app that was autofilled in the previous 85 * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)} 86 * , which is not necessary the same app being autofilled now. 87 */ 88 @Nullable public Bundle getClientState() { 89 return mClientState; 90 } 91 92 /** 93 * Returns the events occurred after the latest call to 94 * {@link FillCallback#onSuccess(FillResponse)}. 95 * 96 * @return The list of events or {@code null} if non occurred. 97 */ 98 @Nullable public List<Event> getEvents() { 99 return mEvents; 100 } 101 102 /** 103 * @hide 104 */ 105 public void addEvent(Event event) { 106 if (mEvents == null) { 107 mEvents = new ArrayList<>(1); 108 } 109 mEvents.add(event); 110 } 111 112 /** 113 * @hide 114 */ 115 public FillEventHistory(int serviceUid, int sessionId, @Nullable Bundle clientState) { 116 mClientState = clientState; 117 mServiceUid = serviceUid; 118 mSessionId = sessionId; 119 } 120 121 @Override 122 public int describeContents() { 123 return 0; 124 } 125 126 @Override 127 public void writeToParcel(Parcel dest, int flags) { 128 dest.writeBundle(mClientState); 129 130 if (mEvents == null) { 131 dest.writeInt(0); 132 } else { 133 dest.writeInt(mEvents.size()); 134 135 int numEvents = mEvents.size(); 136 for (int i = 0; i < numEvents; i++) { 137 Event event = mEvents.get(i); 138 dest.writeInt(event.getType()); 139 dest.writeString(event.getDatasetId()); 140 } 141 } 142 } 143 144 /** 145 * Description of an event that occured after the latest call to 146 * {@link FillCallback#onSuccess(FillResponse)}. 147 */ 148 public static final class Event { 149 /** 150 * A dataset was selected. The dataset selected can be read from {@link #getDatasetId()}. 151 */ 152 public static final int TYPE_DATASET_SELECTED = 0; 153 154 /** 155 * A {@link Dataset.Builder#setAuthentication(IntentSender) dataset authentication} was 156 * selected. The dataset authenticated can be read from {@link #getDatasetId()}. 157 */ 158 public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; 159 160 /** 161 * A {@link FillResponse.Builder#setAuthentication(AutofillId[], IntentSender, RemoteViews) 162 * fill response authentication} was selected. 163 */ 164 public static final int TYPE_AUTHENTICATION_SELECTED = 2; 165 166 /** A save UI was shown. */ 167 public static final int TYPE_SAVE_SHOWN = 3; 168 169 /** @hide */ 170 @IntDef( 171 value = {TYPE_DATASET_SELECTED, 172 TYPE_DATASET_AUTHENTICATION_SELECTED, 173 TYPE_AUTHENTICATION_SELECTED, 174 TYPE_SAVE_SHOWN}) 175 @Retention(RetentionPolicy.SOURCE) 176 @interface EventIds{} 177 178 @EventIds private final int mEventType; 179 @Nullable private final String mDatasetId; 180 181 /** 182 * Returns the type of the event. 183 * 184 * @return The type of the event 185 */ 186 public int getType() { 187 return mEventType; 188 } 189 190 /** 191 * Returns the id of dataset the id was on. 192 * 193 * @return The id of dataset, or {@code null} the event is not associated with a dataset. 194 */ 195 @Nullable public String getDatasetId() { 196 return mDatasetId; 197 } 198 199 /** 200 * Creates a new event. 201 * 202 * @param eventType The type of the event 203 * @param datasetId The dataset the event was on, or {@code null} if the event was on the 204 * whole response. 205 * 206 * @hide 207 */ 208 public Event(int eventType, String datasetId) { 209 mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_SAVE_SHOWN, 210 "eventType"); 211 mDatasetId = datasetId; 212 } 213 } 214 215 public static final Parcelable.Creator<FillEventHistory> CREATOR = 216 new Parcelable.Creator<FillEventHistory>() { 217 @Override 218 public FillEventHistory createFromParcel(Parcel parcel) { 219 FillEventHistory selection = new FillEventHistory(0, 0, parcel.readBundle()); 220 221 int numEvents = parcel.readInt(); 222 for (int i = 0; i < numEvents; i++) { 223 selection.addEvent(new Event(parcel.readInt(), parcel.readString())); 224 } 225 226 return selection; 227 } 228 229 @Override 230 public FillEventHistory[] newArray(int size) { 231 return new FillEventHistory[size]; 232 } 233 }; 234} 235