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 
Voicemail(Long timestamp, String number, PhoneAccountHandle phoneAccountHandle, Long id, Long duration, String source, String providerData, Uri uri, Boolean isRead, Boolean hasContent, String transcription)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      */
createForInsertion(long timestamp, String number)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      */
createForUpdate(long id, String sourceData)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. */
Builder()96         private Builder() {
97         }
98 
setNumber(String number)99         public Builder setNumber(String number) {
100             mBuilderNumber = number;
101             return this;
102         }
103 
setTimestamp(long timestamp)104         public Builder setTimestamp(long timestamp) {
105             mBuilderTimestamp = timestamp;
106             return this;
107         }
108 
setPhoneAccount(PhoneAccountHandle phoneAccount)109         public Builder setPhoneAccount(PhoneAccountHandle phoneAccount) {
110             mBuilderPhoneAccount = phoneAccount;
111             return this;
112         }
113 
setId(long id)114         public Builder setId(long id) {
115             mBuilderId = id;
116             return this;
117         }
118 
setDuration(long duration)119         public Builder setDuration(long duration) {
120             mBuilderDuration = duration;
121             return this;
122         }
123 
setSourcePackage(String sourcePackage)124         public Builder setSourcePackage(String sourcePackage) {
125             mBuilderSourcePackage = sourcePackage;
126             return this;
127         }
128 
setSourceData(String sourceData)129         public Builder setSourceData(String sourceData) {
130             mBuilderSourceData = sourceData;
131             return this;
132         }
133 
setUri(Uri uri)134         public Builder setUri(Uri uri) {
135             mBuilderUri = uri;
136             return this;
137         }
138 
setIsRead(boolean isRead)139         public Builder setIsRead(boolean isRead) {
140             mBuilderIsRead = isRead;
141             return this;
142         }
143 
setHasContent(boolean hasContent)144         public Builder setHasContent(boolean hasContent) {
145             mBuilderHasContent = hasContent;
146             return this;
147         }
148 
setTranscription(String transcription)149         public Builder setTranscription(String transcription) {
150             mBuilderTranscription = transcription;
151             return this;
152         }
153 
build()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      */
getId()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. */
getNumber()177     public String getNumber() {
178         return mNumber;
179     }
180 
181     /** The phone account associated with the voicemail, null if not set. */
getPhoneAccount()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. */
getTimestampMillis()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. */
getDuration()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      */
getSourcePackage()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      */
getSourceData()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      */
getUri()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      */
isRead()230     public boolean isRead() {
231         return mIsRead;
232     }
233 
234     /**
235      * Tells us if there is content stored at the Uri.
236      */
hasContent()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      */
getTranscription()244     public String getTranscription() {
245         return mTranscription;
246     }
247 
248     @Override
describeContents()249     public int describeContents() {
250         return 0;
251     }
252 
253     @Override
writeToParcel(Parcel dest, int flags)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 @android.annotation.NonNull 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 
Voicemail(Parcel in)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