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