• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package android.view.autofill;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.annotation.TestApi;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.view.View;
24 
25 /**
26  * A unique identifier for an autofill node inside an {@link android.app.Activity}.
27  */
28 public final class AutofillId implements Parcelable {
29 
30     /** @hide */
31     public static final int NO_SESSION = 0;
32 
33     private static final int FLAG_IS_VIRTUAL_INT = 0x1;
34     private static final int FLAG_IS_VIRTUAL_LONG = 0x2;
35     private static final int FLAG_HAS_SESSION = 0x4;
36 
37     private final int mViewId;
38     private int mFlags;
39     private final int mVirtualIntId;
40     private final long mVirtualLongId;
41     private int mSessionId;
42 
43     /** @hide */
44     @TestApi
AutofillId(int id)45     public AutofillId(int id) {
46         this(/* flags= */ 0, id, View.NO_ID, NO_SESSION);
47     }
48 
49     /** @hide */
50     @TestApi
AutofillId(@onNull AutofillId hostId, int virtualChildId)51     public AutofillId(@NonNull AutofillId hostId, int virtualChildId) {
52         this(FLAG_IS_VIRTUAL_INT, hostId.mViewId, virtualChildId, NO_SESSION);
53     }
54 
55     /** @hide */
56     @TestApi
AutofillId(int hostId, int virtualChildId)57     public AutofillId(int hostId, int virtualChildId) {
58         this(FLAG_IS_VIRTUAL_INT, hostId, virtualChildId, NO_SESSION);
59     }
60 
61     /** @hide */
62     @TestApi
AutofillId(@onNull AutofillId hostId, long virtualChildId, int sessionId)63     public AutofillId(@NonNull AutofillId hostId, long virtualChildId, int sessionId) {
64         this(FLAG_IS_VIRTUAL_LONG | FLAG_HAS_SESSION, hostId.mViewId, virtualChildId, sessionId);
65     }
66 
AutofillId(int flags, int parentId, long virtualChildId, int sessionId)67     private AutofillId(int flags, int parentId, long virtualChildId, int sessionId) {
68         mFlags = flags;
69         mViewId = parentId;
70         mVirtualIntId = ((flags & FLAG_IS_VIRTUAL_INT) != 0) ? (int) virtualChildId : View.NO_ID;
71         mVirtualLongId = ((flags & FLAG_IS_VIRTUAL_LONG) != 0) ? virtualChildId : View.NO_ID;
72         mSessionId = sessionId;
73     }
74 
75     /** @hide */
76     @NonNull
77     @TestApi
withoutSession(@onNull AutofillId id)78     public static AutofillId withoutSession(@NonNull AutofillId id) {
79         final int flags = id.mFlags & ~FLAG_HAS_SESSION;
80         final long virtualChildId =
81                 ((id.mFlags & FLAG_IS_VIRTUAL_LONG) != 0) ? id.mVirtualLongId
82                         : id.mVirtualIntId;
83         return new AutofillId(flags, id.mViewId, virtualChildId, NO_SESSION);
84     }
85 
86     /** @hide */
getViewId()87     public int getViewId() {
88         return mViewId;
89     }
90 
91     /**
92      * Gets the virtual child id.
93      *
94      * <p>Should only be used on subsystems where such id is represented by an {@code int}
95      * (Assist and Autofill).
96      *
97      * @hide
98      */
getVirtualChildIntId()99     public int getVirtualChildIntId() {
100         return mVirtualIntId;
101     }
102 
103     /**
104      * Gets the virtual child id.
105      *
106      * <p>Should only be used on subsystems where such id is represented by a {@code long}
107      * (ContentCapture).
108      *
109      * @hide
110      */
getVirtualChildLongId()111     public long getVirtualChildLongId() {
112         return mVirtualLongId;
113     }
114 
115     /**
116      * Checks whether this node represents a virtual child, whose id is represented by an
117      * {@code int}.
118      *
119      * <p>Should only be used on subsystems where such id is represented by an {@code int}
120      * (Assist and Autofill).
121      *
122      * @hide
123      */
isVirtualInt()124     public boolean isVirtualInt() {
125         return (mFlags & FLAG_IS_VIRTUAL_INT) != 0;
126     }
127 
128     /**
129      * Checks whether this node represents a virtual child, whose id is represented by an
130      * {@code long}.
131      *
132      * <p>Should only be used on subsystems where such id is represented by a {@code long}
133      * (ContentCapture).
134      *
135      * @hide
136      */
isVirtualLong()137     public boolean isVirtualLong() {
138         return (mFlags & FLAG_IS_VIRTUAL_LONG) != 0;
139     }
140 
141     /**
142      * Checks whether this node represents a non-virtual child.
143      *
144      * @hide
145      */
146     @TestApi
isNonVirtual()147     public boolean isNonVirtual() {
148         return !isVirtualInt() && !isVirtualLong();
149     }
150 
151     /** @hide */
hasSession()152     public boolean hasSession() {
153         return (mFlags & FLAG_HAS_SESSION) != 0;
154     }
155 
156     /** @hide */
getSessionId()157     public int getSessionId() {
158         return mSessionId;
159     }
160 
161     /** @hide */
setSessionId(int sessionId)162     public void setSessionId(int sessionId) {
163         mFlags |= FLAG_HAS_SESSION;
164         mSessionId = sessionId;
165     }
166 
167     /** @hide */
resetSessionId()168     public void resetSessionId() {
169         mFlags &= ~FLAG_HAS_SESSION;
170         mSessionId = NO_SESSION;
171     }
172 
173     /////////////////////////////////
174     //  Object "contract" methods. //
175     /////////////////////////////////
176 
177     @Override
hashCode()178     public int hashCode() {
179         final int prime = 31;
180         int result = 1;
181         result = prime * result + mViewId;
182         result = prime * result + mVirtualIntId;
183         result = prime * result + (int) (mVirtualLongId ^ (mVirtualLongId >>> 32));
184         result = prime * result + mSessionId;
185         return result;
186     }
187 
188     @Override
equals(@ullable Object obj)189     public boolean equals(@Nullable Object obj) {
190         if (this == obj) return true;
191         if (obj == null) return false;
192         if (getClass() != obj.getClass()) return false;
193         final AutofillId other = (AutofillId) obj;
194         if (mViewId != other.mViewId) return false;
195         if (mVirtualIntId != other.mVirtualIntId) return false;
196         if (mVirtualLongId != other.mVirtualLongId) return false;
197         if (mSessionId != other.mSessionId) return false;
198         return true;
199     }
200 
201     /** @hide */
202     @TestApi
equalsIgnoreSession(@ullable AutofillId other)203     public boolean equalsIgnoreSession(@Nullable AutofillId other) {
204         if (this == other) return true;
205         if (other == null) return false;
206         if (mViewId != other.mViewId) return false;
207         if (mVirtualIntId != other.mVirtualIntId) return false;
208         if (mVirtualLongId != other.mVirtualLongId) return false;
209         return true;
210     }
211 
212     @Override
toString()213     public String toString() {
214         final StringBuilder builder = new StringBuilder().append(mViewId);
215         if (isVirtualInt()) {
216             builder.append(':').append(mVirtualIntId);
217         } else if (isVirtualLong()) {
218             builder.append(':').append(mVirtualLongId);
219         }
220 
221         if (hasSession()) {
222             builder.append('@').append(mSessionId);
223         }
224         return builder.toString();
225     }
226 
227     @Override
describeContents()228     public int describeContents() {
229         return 0;
230     }
231 
232     @Override
writeToParcel(Parcel parcel, int flags)233     public void writeToParcel(Parcel parcel, int flags) {
234         parcel.writeInt(mViewId);
235         parcel.writeInt(mFlags);
236         if (hasSession()) {
237             parcel.writeInt(mSessionId);
238         }
239         if (isVirtualInt()) {
240             parcel.writeInt(mVirtualIntId);
241         } else if (isVirtualLong()) {
242             parcel.writeLong(mVirtualLongId);
243         }
244     }
245 
246     public static final @android.annotation.NonNull Parcelable.Creator<AutofillId> CREATOR =
247             new Parcelable.Creator<AutofillId>() {
248         @Override
249         public AutofillId createFromParcel(Parcel source) {
250             final int viewId = source.readInt();
251             final int flags = source.readInt();
252             final int sessionId = (flags & FLAG_HAS_SESSION) != 0 ? source.readInt() : NO_SESSION;
253             if ((flags & FLAG_IS_VIRTUAL_INT) != 0) {
254                 return new AutofillId(flags, viewId, source.readInt(), sessionId);
255             }
256             if ((flags & FLAG_IS_VIRTUAL_LONG) != 0) {
257                 return new AutofillId(flags, viewId, source.readLong(), sessionId);
258             }
259             return new AutofillId(flags, viewId, View.NO_ID, sessionId);
260         }
261 
262         @Override
263         public AutofillId[] newArray(int size) {
264             return new AutofillId[size];
265         }
266     };
267 }
268