• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.providers.contacts;
18 
19 import android.content.ContentUris;
20 import android.content.ContentValues;
21 import android.database.Cursor;
22 import android.net.Uri;
23 import android.os.ParcelFileDescriptor;
24 import android.provider.CallLog.Calls;
25 import android.provider.VoicemailContract;
26 import android.provider.VoicemailContract.Status;
27 import android.provider.VoicemailContract.Voicemails;
28 import android.test.MoreAsserts;
29 import android.test.suitebuilder.annotation.SmallTest;
30 
31 import com.android.common.io.MoreCloseables;
32 
33 import java.io.FileNotFoundException;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.OutputStream;
37 import java.util.Arrays;
38 import java.util.List;
39 
40 /**
41  * Unit tests for {@link VoicemailContentProvider}.
42  *
43  * Run the test like this:
44  * <code>
45  * runtest -c com.android.providers.contacts.VoicemailProviderTest contactsprov
46  * </code>
47  */
48 // TODO: Test that calltype and voicemail_uri are auto populated by the provider.
49 @SmallTest
50 public class VoicemailProviderTest extends BaseVoicemailProviderTest {
51     /** Fields specific to call_log provider that should not be exposed by voicemail provider. */
52     private static final String[] CALLLOG_PROVIDER_SPECIFIC_COLUMNS = {
53             Calls.CACHED_NAME,
54             Calls.CACHED_NUMBER_LABEL,
55             Calls.CACHED_NUMBER_TYPE,
56             Calls.TYPE,
57             Calls.VOICEMAIL_URI,
58             Calls.COUNTRY_ISO
59     };
60     /** Total number of columns exposed by voicemail provider. */
61     private static final int NUM_VOICEMAIL_FIELDS = 14;
62 
63     @Override
setUp()64     protected void setUp() throws Exception {
65         super.setUp();
66         setUpForOwnPermission();
67     }
68 
69     /** Returns the appropriate /voicemail URI. */
voicemailUri()70     private Uri voicemailUri() {
71         return mUseSourceUri ?
72                 Voicemails.buildSourceUri(mActor.packageName) : Voicemails.CONTENT_URI;
73     }
74 
75     /** Returns the appropriate /status URI. */
statusUri()76     private Uri statusUri() {
77         return mUseSourceUri ?
78                 Status.buildSourceUri(mActor.packageName) : Status.CONTENT_URI;
79     }
80 
testInsert()81     public void testInsert() throws Exception {
82         Uri uri = mResolver.insert(voicemailUri(), getTestVoicemailValues());
83         // We create on purpose a new set of ContentValues here, because the code above modifies
84         // the copy it gets.
85         assertStoredValues(uri, getTestVoicemailValues());
86         assertSelection(uri, getTestVoicemailValues(), Voicemails._ID, ContentUris.parseId(uri));
87         assertEquals(1, countFilesInTestDirectory());
88     }
89 
90     // Test to ensure that media content can be written and read back.
testFileContent()91     public void testFileContent() throws Exception {
92         Uri uri = insertVoicemail();
93         OutputStream out = mResolver.openOutputStream(uri);
94         byte[] outBuffer = {0x1, 0x2, 0x3, 0x4};
95         out.write(outBuffer);
96         out.flush();
97         out.close();
98         InputStream in = mResolver.openInputStream(uri);
99         byte[] inBuffer = new byte[4];
100         int numBytesRead = in.read(inBuffer);
101         assertEquals(numBytesRead, outBuffer.length);
102         MoreAsserts.assertEquals(outBuffer, inBuffer);
103         // No more data should be left.
104         assertEquals(-1, in.read(inBuffer));
105         in.close();
106     }
107 
testUpdate()108     public void testUpdate() {
109         Uri uri = insertVoicemail();
110         ContentValues values = new ContentValues();
111         values.put(Voicemails.NUMBER, "1-800-263-7643");
112         values.put(Voicemails.DATE, 2000);
113         values.put(Voicemails.DURATION, 40);
114         values.put(Voicemails.TRANSCRIPTION, "Testing 123");
115         values.put(Voicemails.STATE, 2);
116         values.put(Voicemails.HAS_CONTENT, 1);
117         values.put(Voicemails.SOURCE_DATA, "foo");
118         int count = mResolver.update(uri, values, null, null);
119         assertEquals(1, count);
120         assertStoredValues(uri, values);
121     }
122 
testDelete()123     public void testDelete() {
124         Uri uri = insertVoicemail();
125         int count = mResolver.delete(voicemailUri(), Voicemails._ID + "="
126                 + ContentUris.parseId(uri), null);
127         assertEquals(1, count);
128         assertEquals(0, getCount(uri, null, null));
129     }
130 
testGetType_ItemUri()131     public void testGetType_ItemUri() throws Exception {
132         // Random item uri.
133         assertEquals(Voicemails.ITEM_TYPE,
134                 mResolver.getType(ContentUris.withAppendedId(Voicemails.CONTENT_URI, 100)));
135         // Item uri of an inserted voicemail.
136         ContentValues values = getTestVoicemailValues();
137         values.put(Voicemails.MIME_TYPE, "foo/bar");
138         Uri uri = mResolver.insert(voicemailUri(), values);
139         assertEquals(Voicemails.ITEM_TYPE, mResolver.getType(uri));
140     }
141 
testGetType_DirUri()142     public void testGetType_DirUri() throws Exception {
143         assertEquals(Voicemails.DIR_TYPE, mResolver.getType(Voicemails.CONTENT_URI));
144         assertEquals(Voicemails.DIR_TYPE, mResolver.getType(Voicemails.buildSourceUri("foo")));
145     }
146 
147     // Test to ensure that without full permission it is not possible to use the base uri (i.e. with
148     // no package URI specified).
testMustUsePackageUriWithoutFullPermission()149     public void testMustUsePackageUriWithoutFullPermission() {
150         setUpForOwnPermission();
151         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
152             @Override
153             public void run() {
154                 mResolver.insert(Voicemails.CONTENT_URI, getTestVoicemailValues());
155             }
156         });
157 
158         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
159             @Override
160             public void run() {
161                 mResolver.update(Voicemails.CONTENT_URI, getTestVoicemailValues(), null, null);
162             }
163         });
164 
165         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
166             @Override
167             public void run() {
168                 mResolver.query(Voicemails.CONTENT_URI, null, null, null, null);
169             }
170         });
171 
172         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
173             @Override
174             public void run() {
175                 mResolver.delete(Voicemails.CONTENT_URI, null, null);
176             }
177         });
178     }
179 
testPermissions_InsertAndQuery()180     public void testPermissions_InsertAndQuery() {
181         setUpForFullPermission();
182         // Insert two records - one each with own and another package.
183         insertVoicemail();
184         insertVoicemailForSourcePackage("another-package");
185         assertEquals(2, getCount(voicemailUri(), null, null));
186 
187         // Now give away full permission and check that only 1 message is accessible.
188         setUpForOwnPermission();
189         assertEquals(1, getCount(voicemailUri(), null, null));
190 
191         // Once again try to insert message for another package. This time
192         // it should fail.
193         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
194             @Override
195             public void run() {
196                 insertVoicemailForSourcePackage("another-package");
197             }
198         });
199 
200         setUpForNoPermission();
201         mUseSourceUri = false;
202         // With the READ_ALL_VOICEMAIL permission, we should now be able to read all voicemails
203         mActor.addPermissions(READ_VOICEMAIL_PERMISSION);
204         assertEquals(2, getCount(voicemailUri(), null, null));
205 
206         // An insert for another package should still fail
207         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
208             @Override
209             public void run() {
210                 insertVoicemailForSourcePackage("another-package");
211             }
212         });
213     }
214 
testPermissions_UpdateAndDelete()215     public void testPermissions_UpdateAndDelete() {
216         setUpForFullPermission();
217         // Insert two records - one each with own and another package.
218         final Uri ownVoicemail = insertVoicemail();
219         final Uri anotherVoicemail = insertVoicemailForSourcePackage("another-package");
220         assertEquals(2, getCount(voicemailUri(), null, null));
221 
222         // Now give away full permission and check that we can update and delete only
223         // the own voicemail.
224         setUpForOwnPermission();
225         mResolver.update(withSourcePackageParam(ownVoicemail),
226                 getTestVoicemailValues(), null, null);
227         mResolver.delete(withSourcePackageParam(ownVoicemail), null, null);
228 
229         // However, attempting to update or delete another-package's voicemail should fail.
230         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
231             @Override
232             public void run() {
233                 mResolver.update(anotherVoicemail, null, null, null);
234             }
235         });
236         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
237             @Override
238             public void run() {
239                 mResolver.delete(anotherVoicemail, null, null);
240             }
241         });
242 
243         // If we have the manage voicemail permission, we should be able to both update and delete
244         // voicemails from all packages
245         setUpForNoPermission();
246         mActor.addPermissions(WRITE_VOICEMAIL_PERMISSION);
247         mResolver.update(anotherVoicemail, getTestVoicemailValues(), null, null);
248 
249         // Now add the read voicemail permission temporarily to verify that the update actually
250         // worked
251         mActor.addPermissions(READ_VOICEMAIL_PERMISSION);
252         assertStoredValues(anotherVoicemail, getTestVoicemailValues());
253         mActor.removePermissions(READ_VOICEMAIL_PERMISSION);
254 
255         mResolver.delete(anotherVoicemail, null, null);
256 
257         // Now add the read voicemail permission temporarily to verify that the delete actually
258         // worked
259         mActor.addPermissions(READ_VOICEMAIL_PERMISSION);
260         assertEquals(0, getCount(anotherVoicemail, null, null));
261     }
262 
withSourcePackageParam(Uri uri)263     private Uri withSourcePackageParam(Uri uri) {
264         return uri.buildUpon()
265             .appendQueryParameter(VoicemailContract.PARAM_KEY_SOURCE_PACKAGE, mActor.packageName)
266             .build();
267     }
268 
testUriPermissions()269     public void testUriPermissions() {
270         setUpForFullPermission();
271         final Uri uri1 = insertVoicemail();
272         final Uri uri2 = insertVoicemail();
273         // Give away all permissions before querying. Access to both uris should be denied.
274         setUpForNoPermission();
275         checkHasNoAccessToUri(uri1);
276         checkHasNoAccessToUri(uri2);
277 
278         // Just grant permission to uri1. uri1 should pass but uri2 should still fail.
279         mActor.addUriPermissions(uri1);
280         checkHasReadOnlyAccessToUri(uri1);
281         checkHasNoAccessToUri(uri2);
282 
283         // Cleanup.
284         mActor.removeUriPermissions(uri1);
285     }
286 
287     /*
288      * Checks that the READ_ALL_VOICEMAIL permission provides read access to a uri.
289      */
testUriPermissions_ReadAccess()290     public void testUriPermissions_ReadAccess() {
291         setUpForFullPermission();
292         final Uri uri1 = insertVoicemail();
293         // Give away all permissions before querying. Access should be denied.
294         setUpForNoPermission();
295         mUseSourceUri = false;
296         checkHasNoAccessToUri(uri1);
297 
298         mActor.addPermissions(READ_VOICEMAIL_PERMISSION);
299         checkHasReadAccessToUri(uri1);
300     }
301 
302     /*
303      * Checks that the MANAGE_VOICEMAIL permission provides write access to a uri.
304      */
testUriPermissions_WriteAccess()305     public void testUriPermissions_WriteAccess() {
306         setUpForFullPermission();
307         final Uri uri1 = insertVoicemail();
308         // Give away all permissions before querying. Access should be denied.
309         setUpForNoPermission();
310         checkHasNoAccessToUri(uri1);
311 
312         mActor.addPermissions(WRITE_VOICEMAIL_PERMISSION);
313         checkHasUpdateAndDeleteAccessToUri(uri1);
314     }
315 
checkHasNoAccessToUri(final Uri uri)316     private void checkHasNoAccessToUri(final Uri uri) {
317         checkHasNoReadAccessToUri(uri);
318         checkHasNoWriteAccessToUri(uri);
319     }
320 
checkHasReadOnlyAccessToUri(final Uri uri)321     private void checkHasReadOnlyAccessToUri(final Uri uri) {
322         checkHasReadAccessToUri(uri);
323         checkHasNoWriteAccessToUri(uri);
324     }
325 
checkHasReadAccessToUri(final Uri uri)326     private void checkHasReadAccessToUri(final Uri uri) {
327         Cursor cursor = null;
328         try {
329             cursor = mResolver.query(uri, null, null ,null, null);
330             assertEquals(1, cursor.getCount());
331             try {
332                 ParcelFileDescriptor fd = mResolver.openFileDescriptor(uri, "r");
333                 assertNotNull(fd);
334                 fd.close();
335             } catch (FileNotFoundException e) {
336                 fail(e.getMessage());
337             } catch (IOException e) {
338                 fail(e.getMessage());
339             }
340         } finally {
341             MoreCloseables.closeQuietly(cursor);
342         }
343     }
344 
checkHasNoReadAccessToUri(final Uri uri)345     private void checkHasNoReadAccessToUri(final Uri uri) {
346         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
347             @Override
348             public void run() {
349                 mResolver.query(uri, null, null ,null, null);
350             }
351         });
352         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
353             @Override
354             public void run() {
355                 try {
356                     mResolver.openFileDescriptor(uri, "r");
357                 } catch (FileNotFoundException e) {
358                     fail(e.getMessage());
359                 }
360             }
361         });
362     }
363 
checkHasUpdateAndDeleteAccessToUri(final Uri uri)364     private void checkHasUpdateAndDeleteAccessToUri(final Uri uri) {
365         mResolver.update(uri, getTestVoicemailValues(), null, null);
366         mResolver.delete(uri, null, null);
367     }
368 
checkHasNoWriteAccessToUri(final Uri uri)369     private void checkHasNoWriteAccessToUri(final Uri uri) {
370         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
371             @Override
372             public void run() {
373                 mResolver.update(uri, getTestVoicemailValues(), null, null);
374             }
375         });
376         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
377             @Override
378             public void run() {
379                 mResolver.delete(uri, null, null);
380             }
381         });
382         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
383             @Override
384             public void run() {
385                 try {
386                     mResolver.openFileDescriptor(uri, "w");
387                 } catch (FileNotFoundException e) {
388                     fail(e.getMessage());
389                 }
390             }
391         });
392         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
393             @Override
394             public void run() {
395                 try {
396                     mResolver.openFileDescriptor(uri, "rw");
397                 } catch (FileNotFoundException e) {
398                     fail(e.getMessage());
399                 }
400             }
401         });
402     }
403 
404     // Test to ensure that all operations fail when no voicemail permission is granted.
testNoPermissions()405     public void testNoPermissions() {
406         setUpForNoPermission();
407         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
408             @Override
409             public void run() {
410                 mResolver.insert(voicemailUri(), getTestVoicemailValues());
411             }
412         });
413         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
414             @Override
415             public void run() {
416                 mResolver.update(voicemailUri(), getTestVoicemailValues(), null, null);
417             }
418         });
419         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
420             @Override
421             public void run() {
422                 mResolver.query(voicemailUri(), null, null, null, null);
423             }
424         });
425         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
426             @Override
427             public void run() {
428                 mResolver.delete(voicemailUri(), null, null);
429             }
430         });
431     }
432 
433     // Test to check that none of the call_log provider specific fields are
434     // insertable through voicemail provider.
testCannotAccessCallLogSpecificFields_Insert()435     public void testCannotAccessCallLogSpecificFields_Insert() {
436         for (String callLogColumn : CALLLOG_PROVIDER_SPECIFIC_COLUMNS) {
437             final ContentValues values = getTestVoicemailValues();
438             values.put(callLogColumn, "foo");
439             EvenMoreAsserts.assertThrows("Column: " + callLogColumn,
440                     IllegalArgumentException.class, new Runnable() {
441                     @Override
442                     public void run() {
443                         mResolver.insert(voicemailUri(), values);
444                     }
445                 });
446         }
447     }
448 
449     // Test to check that none of the call_log provider specific fields are
450     // exposed through voicemail provider query.
testCannotAccessCallLogSpecificFields_Query()451     public void testCannotAccessCallLogSpecificFields_Query() {
452         // Query.
453         Cursor cursor = mResolver.query(voicemailUri(), null, null, null, null);
454         List<String> columnNames = Arrays.asList(cursor.getColumnNames());
455         assertEquals(NUM_VOICEMAIL_FIELDS, columnNames.size());
456         // None of the call_log provider specific columns should be present.
457         for (String callLogColumn : CALLLOG_PROVIDER_SPECIFIC_COLUMNS) {
458             assertFalse("Unexpected column: '" + callLogColumn + "' returned.",
459                     columnNames.contains(callLogColumn));
460         }
461     }
462 
463     // Test to check that none of the call_log provider specific fields are
464     // updatable through voicemail provider.
testCannotAccessCallLogSpecificFields_Update()465     public void testCannotAccessCallLogSpecificFields_Update() {
466         for (String callLogColumn : CALLLOG_PROVIDER_SPECIFIC_COLUMNS) {
467             final Uri insertedUri = insertVoicemail();
468             final ContentValues values = getTestVoicemailValues();
469             values.put(callLogColumn, "foo");
470             EvenMoreAsserts.assertThrows("Column: " + callLogColumn,
471                     IllegalArgumentException.class, new Runnable() {
472                     @Override
473                     public void run() {
474                         mResolver.update(insertedUri, values, null, null);
475                     }
476                 });
477         }
478     }
479 
480     // Tests for voicemail status table.
481 
testStatusInsert()482     public void testStatusInsert() throws Exception {
483         ContentValues values = getTestStatusValues();
484         Uri uri = mResolver.insert(statusUri(), values);
485         assertStoredValues(uri, values);
486         assertSelection(uri, values, Status._ID, ContentUris.parseId(uri));
487     }
488 
489     // Test to ensure that duplicate entries for the same package still end up as the same record.
testStatusInsertDuplicate()490     public void testStatusInsertDuplicate() throws Exception {
491         setUpForFullPermission();
492         ContentValues values = getTestStatusValues();
493         assertNotNull(mResolver.insert(statusUri(), values));
494         assertEquals(1, getCount(statusUri(), null, null));
495 
496         // Insertion request for the same package should fail with no change in count.
497         values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_NO_CONNECTION);
498         assertNull(mResolver.insert(statusUri(), values));
499         assertEquals(1, getCount(statusUri(), null, null));
500 
501         // Now insert entry for another source package, and it should end up as a separate record.
502         values.put(Status.SOURCE_PACKAGE, "another.package");
503         assertNotNull(mResolver.insert(statusUri(), values));
504         assertEquals(2, getCount(statusUri(), null, null));
505     }
506 
testStatusUpdate()507     public void testStatusUpdate() throws Exception {
508         Uri uri = insertTestStatusEntry();
509         ContentValues values = getTestStatusValues();
510         values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_NO_CONNECTION);
511         values.put(Status.NOTIFICATION_CHANNEL_STATE,
512                 Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
513         int count = mResolver.update(uri, values, null, null);
514         assertEquals(1, count);
515         assertStoredValues(uri, values);
516     }
517 
testStatusDelete()518     public void testStatusDelete() {
519         Uri uri = insertTestStatusEntry();
520         int count = mResolver.delete(statusUri(), Status._ID + "="
521                 + ContentUris.parseId(uri), null);
522         assertEquals(1, count);
523         assertEquals(0, getCount(uri, null, null));
524     }
525 
testStatusGetType()526     public void testStatusGetType() throws Exception {
527         // Item URI.
528         Uri uri = insertTestStatusEntry();
529         assertEquals(Status.ITEM_TYPE, mResolver.getType(uri));
530 
531         // base URIs.
532         assertEquals(Status.DIR_TYPE, mResolver.getType(Status.CONTENT_URI));
533         assertEquals(Status.DIR_TYPE, mResolver.getType(Status.buildSourceUri("foo")));
534     }
535 
536     // Basic permission checks for the status table.
testStatusPermissions()537     public void testStatusPermissions() throws Exception {
538         final ContentValues values = getTestStatusValues();
539         // Inserting for another package should fail with any of the URIs.
540         values.put(Status.SOURCE_PACKAGE, "another.package");
541         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
542             @Override
543             public void run() {
544                 mResolver.insert(Status.CONTENT_URI, values);
545             }
546         });
547         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
548             @Override
549             public void run() {
550                 mResolver.insert(Status.buildSourceUri(mActor.packageName), values);
551             }
552         });
553 
554         // But insertion with own package should succeed with the right uri.
555         values.put(Status.SOURCE_PACKAGE, mActor.packageName);
556         final Uri uri = mResolver.insert(Status.buildSourceUri(mActor.packageName), values);
557         assertNotNull(uri);
558 
559         // Updating source_package should not work as well.
560         values.put(Status.SOURCE_PACKAGE, "another.package");
561         EvenMoreAsserts.assertThrows(SecurityException.class, new Runnable() {
562             @Override
563             public void run() {
564                 mResolver.update(uri, values, null, null);
565             }
566         });
567     }
568 
569     // File operation is not supported by /status URI.
testStatusFileOperation()570     public void testStatusFileOperation() throws Exception {
571         final Uri uri = insertTestStatusEntry();
572         EvenMoreAsserts.assertThrows(UnsupportedOperationException.class, new Runnable() {
573             @Override
574             public void run() {
575                 try {
576                     mResolver.openOutputStream(uri);
577                 } catch (FileNotFoundException e) {
578                     fail("Unexpected exception " + e);
579                 }
580             }
581         });
582 
583         EvenMoreAsserts.assertThrows(UnsupportedOperationException.class, new Runnable() {
584             @Override
585             public void run() {
586                 try {
587                     mResolver.openInputStream(uri);
588                 } catch (FileNotFoundException e) {
589                     fail("Unexpected exception " + e);
590                 }
591             }
592         });
593     }
594 
595     /**
596      * Inserts a voicemail record with no source package set. The content provider
597      * will detect source package.
598      */
insertVoicemail()599     private Uri insertVoicemail() {
600         return mResolver.insert(voicemailUri(), getTestVoicemailValues());
601     }
602 
603     /** Inserts a voicemail record for the specified source package. */
insertVoicemailForSourcePackage(String sourcePackage)604     private Uri insertVoicemailForSourcePackage(String sourcePackage) {
605         ContentValues values = getTestVoicemailValues();
606         values.put(Voicemails.SOURCE_PACKAGE, sourcePackage);
607         return mResolver.insert(voicemailUri(), values);
608     }
609 
getTestVoicemailValues()610     private ContentValues getTestVoicemailValues() {
611         ContentValues values = new ContentValues();
612         values.put(Voicemails.NUMBER, "1-800-4664-411");
613         values.put(Voicemails.DATE, 1000);
614         values.put(Voicemails.DURATION, 30);
615         values.put(Voicemails.TRANSCRIPTION, "Testing 123");
616         values.put(Voicemails.IS_READ, 0);
617         values.put(Voicemails.HAS_CONTENT, 0);
618         values.put(Voicemails.SOURCE_DATA, "1234");
619         values.put(Voicemails.STATE, Voicemails.STATE_INBOX);
620         return values;
621     }
622 
insertTestStatusEntry()623     private Uri insertTestStatusEntry() {
624         return mResolver.insert(statusUri(), getTestStatusValues());
625     }
626 
getTestStatusValues()627     private ContentValues getTestStatusValues() {
628         ContentValues values = new ContentValues();
629         values.put(Status.SOURCE_PACKAGE, mActor.packageName);
630         values.put(Status.VOICEMAIL_ACCESS_URI, "tel:901");
631         values.put(Status.SETTINGS_URI, "com.example.voicemail.source.SettingsActivity");
632         values.put(Status.CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
633         values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_OK);
634         values.put(Status.NOTIFICATION_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE_OK);
635         return values;
636     }
637 }
638