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