blob: f63628105cba289a9d1d041b186f3944c5e058b3 [file] [log] [blame]
Felipe Leme1dfa9a02018-10-17 17:24:37 -07001/*
2 * Copyright (C) 2018 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 */
16package android.view.intelligence;
17
18import android.annotation.IntDef;
Felipe Leme88eae3b2018-11-07 15:11:56 -080019import android.annotation.NonNull;
Felipe Leme1dfa9a02018-10-17 17:24:37 -070020import android.annotation.Nullable;
21import android.annotation.SystemApi;
22import android.os.Parcel;
23import android.os.Parcelable;
Felipe Leme88eae3b2018-11-07 15:11:56 -080024import android.os.SystemClock;
Felipe Leme1dfa9a02018-10-17 17:24:37 -070025import android.view.autofill.AutofillId;
26
Felipe Leme88eae3b2018-11-07 15:11:56 -080027import com.android.internal.util.Preconditions;
28
29import java.io.PrintWriter;
Felipe Leme1dfa9a02018-10-17 17:24:37 -070030import java.lang.annotation.Retention;
31import java.lang.annotation.RetentionPolicy;
32
33// TODO(b/111276913): add javadocs / implement Parcelable / implement
34/** @hide */
35@SystemApi
36public final class ContentCaptureEvent implements Parcelable {
37
Felipe Leme7a534082018-11-05 15:03:04 -080038 /** @hide */
39 public static final int TYPE_ACTIVITY_DESTROYED = -2;
40 /** @hide */
41 public static final int TYPE_ACTIVITY_CREATED = -1;
42
Felipe Leme1dfa9a02018-10-17 17:24:37 -070043 /**
44 * Called when the activity is started.
45 */
46 public static final int TYPE_ACTIVITY_STARTED = 1;
47
48 /**
49 * Called when the activity is resumed.
50 */
51 public static final int TYPE_ACTIVITY_RESUMED = 2;
52
53 /**
54 * Called when the activity is paused.
55 */
56 public static final int TYPE_ACTIVITY_PAUSED = 3;
57
58 /**
59 * Called when the activity is stopped.
60 */
61 public static final int TYPE_ACTIVITY_STOPPED = 4;
62
63 /**
64 * Called when a node has been added to the screen and is visible to the user.
65 *
66 * <p>The metadata of the node is available through {@link #getViewNode()}.
67 */
Felipe Leme88eae3b2018-11-07 15:11:56 -080068 public static final int TYPE_VIEW_APPEARED = 5;
Felipe Leme1dfa9a02018-10-17 17:24:37 -070069
70 /**
71 * Called when a node has been removed from the screen and is not visible to the user anymore.
72 *
73 * <p>The id of the node is available through {@link #getId()}.
74 */
Felipe Leme88eae3b2018-11-07 15:11:56 -080075 public static final int TYPE_VIEW_DISAPPEARED = 6;
Felipe Leme1dfa9a02018-10-17 17:24:37 -070076
77 /**
78 * Called when the text of a node has been changed.
79 *
80 * <p>The id of the node is available through {@link #getId()}, and the new text is
81 * available through {@link #getText()}.
82 */
83 public static final int TYPE_VIEW_TEXT_CHANGED = 7;
84
85 // TODO(b/111276913): add event to indicate when FLAG_SECURE was changed?
86
87 /** @hide */
88 @IntDef(prefix = { "TYPE_" }, value = {
89 TYPE_ACTIVITY_STARTED,
90 TYPE_ACTIVITY_PAUSED,
91 TYPE_ACTIVITY_RESUMED,
92 TYPE_ACTIVITY_STOPPED,
Felipe Leme88eae3b2018-11-07 15:11:56 -080093 TYPE_VIEW_APPEARED,
94 TYPE_VIEW_DISAPPEARED,
Felipe Leme1dfa9a02018-10-17 17:24:37 -070095 TYPE_VIEW_TEXT_CHANGED
96 })
97 @Retention(RetentionPolicy.SOURCE)
Felipe Leme7a534082018-11-05 15:03:04 -080098 public @interface EventType{}
99
100 private final int mType;
101 private final long mEventTime;
102 private final int mFlags;
Felipe Leme88eae3b2018-11-07 15:11:56 -0800103 private @Nullable AutofillId mId;
104 private @Nullable ViewNode mNode;
105 private @Nullable CharSequence mText;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700106
107 /** @hide */
Felipe Leme7a534082018-11-05 15:03:04 -0800108 public ContentCaptureEvent(int type, long eventTime, int flags) {
109 mType = type;
110 mEventTime = eventTime;
111 mFlags = flags;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700112 }
113
Felipe Leme88eae3b2018-11-07 15:11:56 -0800114
115 /** @hide */
116 public ContentCaptureEvent(int type, int flags) {
117 this(type, SystemClock.uptimeMillis(), flags);
118 }
119
120 /** @hide */
121 public ContentCaptureEvent(int type) {
122 this(type, /* flags= */ 0);
123 }
124
125 /** @hide */
126 public ContentCaptureEvent setAutofillId(@NonNull AutofillId id) {
127 mId = Preconditions.checkNotNull(id);
128 return this;
129 }
130
131 /** @hide */
132 public ContentCaptureEvent setViewNode(@NonNull ViewNode node) {
133 mNode = Preconditions.checkNotNull(node);
134 return this;
135 }
136
137 /** @hide */
138 public ContentCaptureEvent setText(@Nullable CharSequence text) {
139 mText = text;
140 return this;
141 }
142
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700143 /**
144 * Gets the type of the event.
145 *
146 * @return one of {@link #TYPE_ACTIVITY_STARTED}, {@link #TYPE_ACTIVITY_RESUMED},
147 * {@link #TYPE_ACTIVITY_PAUSED}, {@link #TYPE_ACTIVITY_STOPPED},
Felipe Leme88eae3b2018-11-07 15:11:56 -0800148 * {@link #TYPE_VIEW_APPEARED}, {@link #TYPE_VIEW_DISAPPEARED},
149 * or {@link #TYPE_VIEW_TEXT_CHANGED}.
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700150 */
151 public @EventType int getType() {
Felipe Leme7a534082018-11-05 15:03:04 -0800152 return mType;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700153 }
154
155 /**
156 * Gets when the event was generated, in ms.
157 */
158 public long getEventTime() {
Felipe Leme7a534082018-11-05 15:03:04 -0800159 return mEventTime;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700160 }
161
162 /**
163 * Gets optional flags associated with the event.
164 *
165 * @return either {@code 0} or
Felipe Lemeecb08be2018-11-27 15:48:47 -0800166 * {@link android.view.intelligence.ContentCaptureManager#FLAG_USER_INPUT}.
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700167 */
168 public int getFlags() {
Felipe Leme7a534082018-11-05 15:03:04 -0800169 return mFlags;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700170 }
171
172 /**
173 * Gets the whole metadata of the node associated with the event.
174 *
Felipe Leme88eae3b2018-11-07 15:11:56 -0800175 * <p>Only set on {@link #TYPE_VIEW_APPEARED} events.
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700176 */
177 @Nullable
178 public ViewNode getViewNode() {
Felipe Leme88eae3b2018-11-07 15:11:56 -0800179 return mNode;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700180 }
181
182 /**
183 * Gets the {@link AutofillId} of the node associated with the event.
184 *
Felipe Leme88eae3b2018-11-07 15:11:56 -0800185 * <p>Only set on {@link #TYPE_VIEW_DISAPPEARED} and {@link #TYPE_VIEW_TEXT_CHANGED} events.
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700186 */
187 @Nullable
188 public AutofillId getId() {
Felipe Leme88eae3b2018-11-07 15:11:56 -0800189 return mId;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700190 }
191
192 /**
193 * Gets the current text of the node associated with the event.
194 *
195 * <p>Only set on {@link #TYPE_VIEW_TEXT_CHANGED} events.
196 */
197 @Nullable
198 public CharSequence getText() {
Felipe Leme88eae3b2018-11-07 15:11:56 -0800199 return mText;
200 }
201
202 /** @hide */
203 public void dump(@NonNull PrintWriter pw) {
204 pw.print("type="); pw.print(getTypeAsString(mType));
205 pw.print(", time="); pw.print(mEventTime);
206 if (mFlags > 0) {
207 pw.print(", flags="); pw.print(mFlags);
208 }
209 if (mId != null) {
210 pw.print(", id="); pw.print(mId);
211 }
212 if (mNode != null) {
213 pw.print(", id="); pw.print(mNode.getAutofillId());
214 }
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700215 }
216
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700217 @Override
Felipe Leme7a534082018-11-05 15:03:04 -0800218 public String toString() {
219 final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
Felipe Leme88eae3b2018-11-07 15:11:56 -0800220 .append(getTypeAsString(mType));
Felipe Leme7a534082018-11-05 15:03:04 -0800221 if (mFlags > 0) {
222 string.append(", flags=").append(mFlags);
223 }
Felipe Leme88eae3b2018-11-07 15:11:56 -0800224 if (mId != null) {
225 string.append(", id=").append(mId);
226 }
227 if (mNode != null) {
228 final String className = mNode.getClassName();
229 if (mNode != null) {
230 string.append(", class=").append(className);
231 }
232 string.append(", id=").append(mNode.getAutofillId());
233 }
Felipe Leme7a534082018-11-05 15:03:04 -0800234 return string.append(']').toString();
235 }
236
237 @Override
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700238 public int describeContents() {
239 return 0;
240 }
241
242 @Override
243 public void writeToParcel(Parcel parcel, int flags) {
Felipe Leme7a534082018-11-05 15:03:04 -0800244 parcel.writeInt(mType);
245 parcel.writeLong(mEventTime);
246 parcel.writeInt(mFlags);
Felipe Leme88eae3b2018-11-07 15:11:56 -0800247 parcel.writeParcelable(mId, flags);
248 ViewNode.writeToParcel(parcel, mNode, flags);
249 parcel.writeCharSequence(mText);
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700250 }
251
252 public static final Parcelable.Creator<ContentCaptureEvent> CREATOR =
253 new Parcelable.Creator<ContentCaptureEvent>() {
254
255 @Override
256 public ContentCaptureEvent createFromParcel(Parcel parcel) {
Felipe Leme7a534082018-11-05 15:03:04 -0800257 final int type = parcel.readInt();
258 final long eventTime = parcel.readLong();
259 final int flags = parcel.readInt();
Felipe Leme88eae3b2018-11-07 15:11:56 -0800260 final ContentCaptureEvent event = new ContentCaptureEvent(type, eventTime, flags);
261 final AutofillId id = parcel.readParcelable(null);
262 if (id != null) {
263 event.setAutofillId(id);
264 }
265 final ViewNode node = ViewNode.readFromParcel(parcel);
266 if (node != null) {
267 event.setViewNode(node);
268 }
269 event.setText(parcel.readCharSequence());
270 return event;
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700271 }
272
273 @Override
274 public ContentCaptureEvent[] newArray(int size) {
275 return new ContentCaptureEvent[size];
276 }
277 };
Felipe Leme7a534082018-11-05 15:03:04 -0800278
Felipe Leme7a534082018-11-05 15:03:04 -0800279 /** @hide */
280 public static String getTypeAsString(@EventType int type) {
281 switch (type) {
282 case TYPE_ACTIVITY_STARTED:
283 return "ACTIVITY_STARTED";
284 case TYPE_ACTIVITY_RESUMED:
285 return "ACTIVITY_RESUMED";
286 case TYPE_ACTIVITY_PAUSED:
287 return "ACTIVITY_PAUSED";
288 case TYPE_ACTIVITY_STOPPED:
289 return "ACTIVITY_STOPPED";
Felipe Leme88eae3b2018-11-07 15:11:56 -0800290 case TYPE_VIEW_APPEARED:
291 return "VIEW_APPEARED";
292 case TYPE_VIEW_DISAPPEARED:
293 return "VIEW_DISAPPEARED";
Felipe Leme7a534082018-11-05 15:03:04 -0800294 case TYPE_VIEW_TEXT_CHANGED:
295 return "VIEW_TEXT_CHANGED";
296 default:
297 return "UKNOWN_TYPE: " + type;
298 }
299 }
Felipe Leme1dfa9a02018-10-17 17:24:37 -0700300}