blob: 63ef2484ca1df4ff501b71fa69f4c2270a9bb4d0 [file] [log] [blame]
Selim Cinek9acd6732018-03-23 16:39:02 -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 */
16
17package android.app;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.graphics.drawable.Icon;
Mady Mellor726df922020-01-29 11:41:58 -080022import android.net.Uri;
Selim Cinek9acd6732018-03-23 16:39:02 -070023import android.os.Parcel;
24import android.os.Parcelable;
25
Beverlye98937a2018-11-15 10:18:57 -050026import java.util.Objects;
27
Selim Cinek9acd6732018-03-23 16:39:02 -070028/**
29 * Provides an immutable reference to an entity that appears repeatedly on different surfaces of the
30 * platform. For example, this could represent the sender of a message.
31 */
32public final class Person implements Parcelable {
33
34 @Nullable private CharSequence mName;
35 @Nullable private Icon mIcon;
36 @Nullable private String mUri;
37 @Nullable private String mKey;
38 private boolean mIsBot;
39 private boolean mIsImportant;
40
41 private Person(Parcel in) {
42 mName = in.readCharSequence();
43 if (in.readInt() != 0) {
44 mIcon = Icon.CREATOR.createFromParcel(in);
45 }
46 mUri = in.readString();
47 mKey = in.readString();
48 mIsImportant = in.readBoolean();
49 mIsBot = in.readBoolean();
50 }
51
52 private Person(Builder builder) {
53 mName = builder.mName;
54 mIcon = builder.mIcon;
55 mUri = builder.mUri;
56 mKey = builder.mKey;
57 mIsBot = builder.mIsBot;
58 mIsImportant = builder.mIsImportant;
59 }
60
61 /** Creates and returns a new {@link Builder} initialized with this Person's data. */
62 public Builder toBuilder() {
63 return new Builder(this);
64 }
65
66 /**
67 * @return the uri provided for this person or {@code null} if no Uri was provided.
68 */
69 @Nullable
70 public String getUri() {
71 return mUri;
72 }
73
74 /**
75 * @return the name provided for this person or {@code null} if no name was provided.
76 */
77 @Nullable
78 public CharSequence getName() {
79 return mName;
80 }
81
82 /**
83 * @return the icon provided for this person or {@code null} if no icon was provided.
84 */
85 @Nullable
86 public Icon getIcon() {
87 return mIcon;
88 }
89
90 /**
91 * @return the key provided for this person or {@code null} if no key was provided.
92 */
93 @Nullable
94 public String getKey() {
95 return mKey;
96 }
97
98 /**
99 * @return whether this Person is a machine.
100 */
101 public boolean isBot() {
102 return mIsBot;
103 }
104
105 /**
106 * @return whether this Person is important.
107 */
108 public boolean isImportant() {
109 return mIsImportant;
110 }
111
112 /**
113 * @return the URI associated with this person, or "name:mName" otherwise
114 * @hide
115 */
116 public String resolveToLegacyUri() {
117 if (mUri != null) {
118 return mUri;
119 }
120 if (mName != null) {
121 return "name:" + mName;
122 }
123 return "";
124 }
125
Mady Mellor726df922020-01-29 11:41:58 -0800126 /**
127 * @return the URI associated with the {@link #getIcon()} for this person, iff the icon exists
128 * and is URI based.
129 * @hide
130 */
131 @Nullable
132 public Uri getIconUri() {
133 if (mIcon != null && (mIcon.getType() == Icon.TYPE_URI
134 || mIcon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
135 return mIcon.getUri();
136 }
137 return null;
138 }
139
Selim Cinek9acd6732018-03-23 16:39:02 -0700140 @Override
Beverlye98937a2018-11-15 10:18:57 -0500141 public boolean equals(Object obj) {
142 if (obj instanceof Person) {
143 final Person other = (Person) obj;
144 return Objects.equals(mName, other.mName)
Tony Makf99ee172018-11-23 12:14:39 +0000145 && (mIcon == null ? other.mIcon == null :
146 (other.mIcon != null && mIcon.sameAs(other.mIcon)))
Beverlye98937a2018-11-15 10:18:57 -0500147 && Objects.equals(mUri, other.mUri)
148 && Objects.equals(mKey, other.mKey)
149 && mIsBot == other.mIsBot
150 && mIsImportant == other.mIsImportant;
151 }
152 return false;
153 }
154
155 @Override
156 public int hashCode() {
157 return Objects.hash(mName, mIcon, mUri, mKey, mIsBot, mIsImportant);
158 }
159
160 @Override
Selim Cinek9acd6732018-03-23 16:39:02 -0700161 public int describeContents() {
162 return 0;
163 }
164
165 @Override
166 public void writeToParcel(Parcel dest, @WriteFlags int flags) {
167 dest.writeCharSequence(mName);
168 if (mIcon != null) {
169 dest.writeInt(1);
170 mIcon.writeToParcel(dest, 0);
171 } else {
172 dest.writeInt(0);
173 }
174 dest.writeString(mUri);
175 dest.writeString(mKey);
176 dest.writeBoolean(mIsImportant);
177 dest.writeBoolean(mIsBot);
178 }
179
180 /** Builder for the immutable {@link Person} class. */
181 public static class Builder {
182 @Nullable private CharSequence mName;
183 @Nullable private Icon mIcon;
184 @Nullable private String mUri;
185 @Nullable private String mKey;
186 private boolean mIsBot;
187 private boolean mIsImportant;
188
189 /** Creates a new, empty {@link Builder}. */
190 public Builder() {
191 }
192
193 private Builder(Person person) {
194 mName = person.mName;
195 mIcon = person.mIcon;
196 mUri = person.mUri;
197 mKey = person.mKey;
198 mIsBot = person.mIsBot;
199 mIsImportant = person.mIsImportant;
200 }
201
202 /**
203 * Give this person a name.
204 *
205 * @param name the name of this person.
206 */
207 @NonNull
208 public Person.Builder setName(@Nullable CharSequence name) {
209 this.mName = name;
210 return this;
211 }
212
213 /**
214 * Add an icon for this person.
215 * <br />
216 * The system will prefer this icon over any images that are resolved from the URI.
217 *
218 * @param icon the icon of the person.
219 */
220 @NonNull
221 public Person.Builder setIcon(@Nullable Icon icon) {
222 this.mIcon = icon;
223 return this;
224 }
225
226 /**
227 * Set a URI associated with this person.
228 *
229 * <P>
230 * The person should be specified by the {@code String} representation of a
231 * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
232 * </P>
233 *
234 * <P>The system will also attempt to resolve {@code mailto:} and {@code tel:} schema
235 * URIs. The path part of these URIs must exist in the contacts database, in the
236 * appropriate column, or the reference will be discarded as invalid. Telephone schema
237 * URIs will be resolved by {@link android.provider.ContactsContract.PhoneLookup}.
238 * </P>
239 *
240 * @param uri a URI for the person.
241 */
242 @NonNull
243 public Person.Builder setUri(@Nullable String uri) {
244 mUri = uri;
245 return this;
246 }
247
248 /**
249 * Add a key to this person in order to uniquely identify it.
250 * This is especially useful if the name doesn't uniquely identify this person or if the
251 * display name is a short handle of the actual name.
252 *
253 * <P>If no key is provided, the name serves as the key for the purpose of
254 * identification.</P>
255 *
256 * @param key the key that uniquely identifies this person.
257 */
258 @NonNull
259 public Person.Builder setKey(@Nullable String key) {
260 mKey = key;
261 return this;
262 }
263
264 /**
265 * Sets whether this is an important person. Use this method to denote users who frequently
266 * interact with the user of this device when {@link #setUri(String)} isn't provided with
267 * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, and instead with
268 * the {@code mailto:} or {@code tel:} schemas.
269 *
270 * @param isImportant {@code true} if this is an important person, {@code false} otherwise.
271 */
272 @NonNull
273 public Person.Builder setImportant(boolean isImportant) {
274 mIsImportant = isImportant;
275 return this;
276 }
277
278 /**
279 * Sets whether this person is a machine rather than a human.
280 *
281 * @param isBot {@code true} if this person is a machine, {@code false} otherwise.
282 */
283 @NonNull
284 public Person.Builder setBot(boolean isBot) {
285 mIsBot = isBot;
286 return this;
287 }
288
289 /** Creates and returns the {@link Person} this builder represents. */
290 @NonNull
291 public Person build() {
292 return new Person(this);
293 }
294 }
295
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700296 public static final @android.annotation.NonNull Creator<Person> CREATOR = new Creator<Person>() {
Selim Cinek9acd6732018-03-23 16:39:02 -0700297 @Override
298 public Person createFromParcel(Parcel in) {
299 return new Person(in);
300 }
301
302 @Override
303 public Person[] newArray(int size) {
304 return new Person[size];
305 }
306 };
307}