Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2016 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 com.android.voicemail.impl;
     18 
     19 import android.net.Uri;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 import android.telecom.PhoneAccountHandle;
     23 import android.text.TextUtils;
     24 
     25 /** Represents a single voicemail stored in the voicemail content provider. */
     26 public class Voicemail implements Parcelable {
     27 
     28   private final Long timestamp;
     29   private final String number;
     30   private final PhoneAccountHandle phoneAccount;
     31   private final Long id;
     32   private final Long duration;
     33   private final String source;
     34   private final String providerData;
     35   private final Uri uri;
     36   private final Boolean isRead;
     37   private final Boolean hasContent;
     38   private final String transcription;
     39 
     40   private Voicemail(
     41       Long timestamp,
     42       String number,
     43       PhoneAccountHandle phoneAccountHandle,
     44       Long id,
     45       Long duration,
     46       String source,
     47       String providerData,
     48       Uri uri,
     49       Boolean isRead,
     50       Boolean hasContent,
     51       String transcription) {
     52     this.timestamp = timestamp;
     53     this.number = number;
     54     phoneAccount = phoneAccountHandle;
     55     this.id = id;
     56     this.duration = duration;
     57     this.source = source;
     58     this.providerData = providerData;
     59     this.uri = uri;
     60     this.isRead = isRead;
     61     this.hasContent = hasContent;
     62     this.transcription = transcription;
     63   }
     64 
     65   /**
     66    * Create a {@link Builder} for a new {@link Voicemail} to be inserted.
     67    *
     68    * <p>The number and the timestamp are mandatory for insertion.
     69    */
     70   public static Builder createForInsertion(long timestamp, String number) {
     71     return new Builder().setNumber(number).setTimestamp(timestamp);
     72   }
     73 
     74   /**
     75    * Create a {@link Builder} for a {@link Voicemail} to be updated (or deleted).
     76    *
     77    * <p>The id and source data fields are mandatory for update - id is necessary for updating the
     78    * database and source data is necessary for updating the server.
     79    */
     80   public static Builder createForUpdate(long id, String sourceData) {
     81     return new Builder().setId(id).setSourceData(sourceData);
     82   }
     83 
     84   /**
     85    * Builder pattern for creating a {@link Voicemail}. The builder must be created with the {@link
     86    * #createForInsertion(long, String)} method.
     87    *
     88    * <p>This class is <b>not thread safe</b>
     89    */
     90   public static class Builder {
     91 
     92     private Long builderTimestamp;
     93     private String builderNumber;
     94     private PhoneAccountHandle builderPhoneAccount;
     95     private Long builderId;
     96     private Long builderDuration;
     97     private String builderSourcePackage;
     98     private String builderSourceData;
     99     private Uri builderUri;
    100     private Boolean builderIsRead;
    101     private boolean builderHasContent;
    102     private String builderTranscription;
    103 
    104     /** You should use the correct factory method to construct a builder. */
    105     private Builder() {}
    106 
    107     public Builder setNumber(String number) {
    108       builderNumber = number;
    109       return this;
    110     }
    111 
    112     public Builder setTimestamp(long timestamp) {
    113       builderTimestamp = timestamp;
    114       return this;
    115     }
    116 
    117     public Builder setPhoneAccount(PhoneAccountHandle phoneAccount) {
    118       builderPhoneAccount = phoneAccount;
    119       return this;
    120     }
    121 
    122     public Builder setId(long id) {
    123       builderId = id;
    124       return this;
    125     }
    126 
    127     public Builder setDuration(long duration) {
    128       builderDuration = duration;
    129       return this;
    130     }
    131 
    132     public Builder setSourcePackage(String sourcePackage) {
    133       builderSourcePackage = sourcePackage;
    134       return this;
    135     }
    136 
    137     public Builder setSourceData(String sourceData) {
    138       builderSourceData = sourceData;
    139       return this;
    140     }
    141 
    142     public Builder setUri(Uri uri) {
    143       builderUri = uri;
    144       return this;
    145     }
    146 
    147     public Builder setIsRead(boolean isRead) {
    148       builderIsRead = isRead;
    149       return this;
    150     }
    151 
    152     public Builder setHasContent(boolean hasContent) {
    153       builderHasContent = hasContent;
    154       return this;
    155     }
    156 
    157     public Builder setTranscription(String transcription) {
    158       builderTranscription = transcription;
    159       return this;
    160     }
    161 
    162     public Voicemail build() {
    163       builderId = builderId == null ? -1 : builderId;
    164       builderTimestamp = builderTimestamp == null ? 0 : builderTimestamp;
    165       builderDuration = builderDuration == null ? 0 : builderDuration;
    166       builderIsRead = builderIsRead == null ? false : builderIsRead;
    167       return new Voicemail(
    168           builderTimestamp,
    169           builderNumber,
    170           builderPhoneAccount,
    171           builderId,
    172           builderDuration,
    173           builderSourcePackage,
    174           builderSourceData,
    175           builderUri,
    176           builderIsRead,
    177           builderHasContent,
    178           builderTranscription);
    179     }
    180   }
    181 
    182   /**
    183    * The identifier of the voicemail in the content provider.
    184    *
    185    * <p>This may be missing in the case of a new {@link Voicemail} that we plan to insert into the
    186    * content provider, since until it has been inserted we don't know what id it should have. If
    187    * none is specified, we return -1.
    188    */
    189   public long getId() {
    190     return id;
    191   }
    192 
    193   /** The number of the person leaving the voicemail, empty string if unknown, null if not set. */
    194   public String getNumber() {
    195     return number;
    196   }
    197 
    198   /** The phone account associated with the voicemail, null if not set. */
    199   public PhoneAccountHandle getPhoneAccount() {
    200     return phoneAccount;
    201   }
    202 
    203   /** The timestamp the voicemail was received, in millis since the epoch, zero if not set. */
    204   public long getTimestampMillis() {
    205     return timestamp;
    206   }
    207 
    208   /** Gets the duration of the voicemail in millis, or zero if the field is not set. */
    209   public long getDuration() {
    210     return duration;
    211   }
    212 
    213   /**
    214    * Returns the package name of the source that added this voicemail, or null if this field is not
    215    * set.
    216    */
    217   public String getSourcePackage() {
    218     return source;
    219   }
    220 
    221   /**
    222    * Returns the application-specific data type stored with the voicemail, or null if this field is
    223    * not set.
    224    *
    225    * <p>Source data is typically used as an identifier to uniquely identify the voicemail against
    226    * the voicemail server. This is likely to be something like the IMAP UID, or some other
    227    * server-generated identifying string.
    228    */
    229   public String getSourceData() {
    230     return providerData;
    231   }
    232 
    233   /**
    234    * Gets the Uri that can be used to refer to this voicemail, and to make it play.
    235    *
    236    * <p>Returns null if we don't know the Uri.
    237    */
    238   public Uri getUri() {
    239     return uri;
    240   }
    241 
    242   /**
    243    * Tells us if the voicemail message has been marked as read.
    244    *
    245    * <p>Always returns false if this field has not been set, i.e. if hasRead() returns false.
    246    */
    247   public boolean isRead() {
    248     return isRead;
    249   }
    250 
    251   /** Tells us if there is content stored at the Uri. */
    252   public boolean hasContent() {
    253     return hasContent;
    254   }
    255 
    256   /** Returns the text transcription of this voicemail, or null if this field is not set. */
    257   public String getTranscription() {
    258     return transcription;
    259   }
    260 
    261   @Override
    262   public int describeContents() {
    263     return 0;
    264   }
    265 
    266   @Override
    267   public void writeToParcel(Parcel dest, int flags) {
    268     dest.writeLong(timestamp);
    269     writeCharSequence(dest, number);
    270     if (phoneAccount == null) {
    271       dest.writeInt(0);
    272     } else {
    273       dest.writeInt(1);
    274       phoneAccount.writeToParcel(dest, flags);
    275     }
    276     dest.writeLong(id);
    277     dest.writeLong(duration);
    278     writeCharSequence(dest, source);
    279     writeCharSequence(dest, providerData);
    280     if (uri == null) {
    281       dest.writeInt(0);
    282     } else {
    283       dest.writeInt(1);
    284       uri.writeToParcel(dest, flags);
    285     }
    286     if (isRead) {
    287       dest.writeInt(1);
    288     } else {
    289       dest.writeInt(0);
    290     }
    291     if (hasContent) {
    292       dest.writeInt(1);
    293     } else {
    294       dest.writeInt(0);
    295     }
    296     writeCharSequence(dest, transcription);
    297   }
    298 
    299   public static final Creator<Voicemail> CREATOR =
    300       new Creator<Voicemail>() {
    301         @Override
    302         public Voicemail createFromParcel(Parcel in) {
    303           return new Voicemail(in);
    304         }
    305 
    306         @Override
    307         public Voicemail[] newArray(int size) {
    308           return new Voicemail[size];
    309         }
    310       };
    311 
    312   private Voicemail(Parcel in) {
    313     timestamp = in.readLong();
    314     number = (String) readCharSequence(in);
    315     if (in.readInt() > 0) {
    316       phoneAccount = PhoneAccountHandle.CREATOR.createFromParcel(in);
    317     } else {
    318       phoneAccount = null;
    319     }
    320     id = in.readLong();
    321     duration = in.readLong();
    322     source = (String) readCharSequence(in);
    323     providerData = (String) readCharSequence(in);
    324     if (in.readInt() > 0) {
    325       uri = Uri.CREATOR.createFromParcel(in);
    326     } else {
    327       uri = null;
    328     }
    329     isRead = in.readInt() > 0 ? true : false;
    330     hasContent = in.readInt() > 0 ? true : false;
    331     transcription = (String) readCharSequence(in);
    332   }
    333 
    334   private static CharSequence readCharSequence(Parcel in) {
    335     return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
    336   }
    337 
    338   public static void writeCharSequence(Parcel dest, CharSequence val) {
    339     TextUtils.writeToParcel(val, dest, 0);
    340   }
    341 }
    342