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
17package android.telecom;
18
19import android.net.Uri;
20import android.os.Parcel;
21import android.os.Parcelable;
22
23/**
24 * Represents a single voicemail stored in the voicemail content provider.
25 *
26 * @hide
27 */
28public 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