content: /*
   * Copyright (C) 2018 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.app;
  
  import android.annotation.NonNull;
  import android.annotation.Nullable;
  import android.graphics.drawable.Icon;
  import android.os.Parcel;
  import android.os.Parcelable;
  
  import java.util.Objects;
  
  /**
   * Provides an immutable reference to an entity that appears repeatedly on different surfaces of the
   * platform. For example, this could represent the sender of a message.
   */
  public final class Person implements Parcelable {
  
      @Nullable private CharSequence mName;
      @Nullable private Icon mIcon;
      @Nullable private String mUri;
      @Nullable private String mKey;
      private boolean mIsBot;
      private boolean mIsImportant;
  
      private Person(Parcel in) {
          mName = in.readCharSequence();
          if (in.readInt() != 0) {
              mIcon = Icon.CREATOR.createFromParcel(in);
          }
          mUri = in.readString();
          mKey = in.readString();
          mIsImportant = in.readBoolean();
          mIsBot = in.readBoolean();
      }
  
      private Person(Builder builder) {
          mName = builder.mName;
          mIcon = builder.mIcon;
          mUri = builder.mUri;
          mKey = builder.mKey;
          mIsBot = builder.mIsBot;
          mIsImportant = builder.mIsImportant;
      }
  
      /** Creates and returns a new {@link Builder} initialized with this Person's data. */
      public Builder toBuilder() {
          return new Builder(this);
      }
  
      /**
       * @return the uri provided for this person or {@code null} if no Uri was provided.
       */
      @Nullable
      public String getUri() {
          return mUri;
      }
  
      /**
       * @return the name provided for this person or {@code null} if no name was provided.
       */
      @Nullable
      public CharSequence getName() {
          return mName;
      }
  
      /**
       * @return the icon provided for this person or {@code null} if no icon was provided.
       */
      @Nullable
      public Icon getIcon() {
          return mIcon;
      }
  
      /**
       * @return the key provided for this person or {@code null} if no key was provided.
       */
      @Nullable
      public String getKey() {
          return mKey;
      }
  
      /**
       * @return whether this Person is a machine.
       */
      public boolean isBot() {
          return mIsBot;
      }
  
      /**
       * @return whether this Person is important.
       */
      public boolean isImportant() {
          return mIsImportant;
      }
  
      /**
       * @return the URI associated with this person, or "name:mName" otherwise
       *  @hide
       */
      public String resolveToLegacyUri() {
          if (mUri != null) {
              return mUri;
          }
          if (mName != null) {
              return "name:" + mName;
          }
          return "";
      }
  
      @Override
      public boolean equals(Object obj) {
          if (obj instanceof Person) {
              final Person other = (Person) obj;
              return Objects.equals(mName, other.mName)
                      && (mIcon == null ? other.mIcon == null :
                      (other.mIcon != null && mIcon.sameAs(other.mIcon)))
                      && Objects.equals(mUri, other.mUri)
                      && Objects.equals(mKey, other.mKey)
                      && mIsBot == other.mIsBot
                      && mIsImportant == other.mIsImportant;
          }
          return false;
      }
  
      @Override
      public int hashCode() {
          return Objects.hash(mName, mIcon, mUri, mKey, mIsBot, mIsImportant);
      }
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      @Override
      public void writeToParcel(Parcel dest, @WriteFlags int flags) {
          dest.writeCharSequence(mName);
          if (mIcon != null) {
              dest.writeInt(1);
              mIcon.writeToParcel(dest, 0);
          } else {
              dest.writeInt(0);
          }
          dest.writeString(mUri);
          dest.writeString(mKey);
          dest.writeBoolean(mIsImportant);
          dest.writeBoolean(mIsBot);
      }
  
      /** Builder for the immutable {@link Person} class. */
      public static class Builder {
          @Nullable private CharSequence mName;
          @Nullable private Icon mIcon;
          @Nullable private String mUri;
          @Nullable private String mKey;
          private boolean mIsBot;
          private boolean mIsImportant;
  
          /** Creates a new, empty {@link Builder}. */
          public Builder() {
          }
  
          private Builder(Person person) {
              mName = person.mName;
              mIcon = person.mIcon;
              mUri = person.mUri;
              mKey = person.mKey;
              mIsBot = person.mIsBot;
              mIsImportant = person.mIsImportant;
          }
  
          /**
           * Give this person a name.
           *
           * @param name the name of this person.
           */
          @NonNull
          public Person.Builder setName(@Nullable CharSequence name) {
              this.mName = name;
              return this;
          }
  
          /**
           * Add an icon for this person.
           * <br />
           * The system will prefer this icon over any images that are resolved from the URI.
           *
           * @param icon the icon of the person.
           */
          @NonNull
          public Person.Builder setIcon(@Nullable Icon icon) {
              this.mIcon = icon;
              return this;
          }
  
          /**
           * Set a URI associated with this person.
           *
           * <P>
           * The person should be specified by the {@code String} representation of a
           * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
           * </P>
           *
           * <P>The system will also attempt to resolve {@code mailto:} and {@code tel:} schema
           * URIs. The path part of these URIs must exist in the contacts database, in the
           * appropriate column, or the reference will be discarded as invalid. Telephone schema
           * URIs will be resolved by {@link android.provider.ContactsContract.PhoneLookup}.
           * </P>
           *
           * @param uri a URI for the person.
           */
          @NonNull
          public Person.Builder setUri(@Nullable String uri) {
              mUri = uri;
              return this;
          }
  
          /**
           * Add a key to this person in order to uniquely identify it.
           * This is especially useful if the name doesn't uniquely identify this person or if the
           * display name is a short handle of the actual name.
           *
           * <P>If no key is provided, the name serves as the key for the purpose of
           * identification.</P>
           *
           * @param key the key that uniquely identifies this person.
           */
          @NonNull
          public Person.Builder setKey(@Nullable String key) {
              mKey = key;
              return this;
          }
  
          /**
           * Sets whether this is an important person. Use this method to denote users who frequently
           * interact with the user of this device when {@link #setUri(String)} isn't provided with
           * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, and instead with
           * the {@code mailto:} or {@code tel:} schemas.
           *
           * @param isImportant {@code true} if this is an important person, {@code false} otherwise.
           */
          @NonNull
          public Person.Builder setImportant(boolean isImportant) {
              mIsImportant = isImportant;
              return this;
          }
  
          /**
           * Sets whether this person is a machine rather than a human.
           *
           * @param isBot {@code true} if this person is a machine, {@code false} otherwise.
           */
          @NonNull
          public Person.Builder setBot(boolean isBot) {
              mIsBot = isBot;
              return this;
          }
  
          /** Creates and returns the {@link Person} this builder represents. */
          @NonNull
          public Person build() {
              return new Person(this);
          }
      }
  
      public static final @android.annotation.NonNull Creator<Person> CREATOR = new Creator<Person>() {
          @Override
          public Person createFromParcel(Parcel in) {
              return new Person(in);
          }
  
          @Override
          public Person[] newArray(int size) {
              return new Person[size];
          }
      };
  }
  