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