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 android.provider.cts;
18 
19 import android.content.ContentProviderClient;
20 import android.content.ContentResolver;
21 import android.content.ContentValues;
22 import android.database.Cursor;
23 import android.net.Uri;
24 import android.os.RemoteException;
25 import android.provider.VoicemailContract;
26 import android.provider.VoicemailContract.Status;
27 import android.provider.VoicemailContract.Voicemails;
28 import android.test.InstrumentationTestCase;
29 
30 /**
31  * CTS tests for voicemail provider accessed through {@link VoicemailContract}.
32  */
33 public class VoicemailContractTest extends InstrumentationTestCase {
34     private ContentResolver mContentResolver;
35     private ContentProviderClient mVoicemailProvider;
36     private ContentProviderClient mStatusProvider;
37     private Uri mVoicemailContentUri;
38     private Uri mStatusContentUri;
39     private String mSourcePackageName;
40 
41     @Override
setUp()42     protected void setUp() throws Exception {
43         super.setUp();
44         mSourcePackageName = getInstrumentation().getTargetContext().getPackageName();
45         mVoicemailContentUri = Voicemails.buildSourceUri(mSourcePackageName);
46         mStatusContentUri = Status.buildSourceUri(mSourcePackageName);
47         mContentResolver = getInstrumentation().getTargetContext().getContentResolver();
48         mVoicemailProvider = mContentResolver.acquireContentProviderClient(mVoicemailContentUri);
49         mStatusProvider = mContentResolver.acquireContentProviderClient(mStatusContentUri);
50     }
51 
52     @Override
tearDown()53     protected void tearDown() throws Exception {
54         // Clean up, just in case we failed to delete the entry when a test failed.
55         // The cotentUris are specific to this package, so this will delete only the
56         // entries inserted by this package.
57         mStatusProvider.delete(mStatusContentUri, null, null);
58         mVoicemailProvider.delete(mVoicemailContentUri, null, null);
59         super.tearDown();
60     }
61 
testVoicemailsTable()62     public void testVoicemailsTable() throws Exception {
63         final String[] VOICEMAILS_PROJECTION = new String[] {
64                 Voicemails._ID, Voicemails.NUMBER, Voicemails.DATE, Voicemails.DURATION,
65                 Voicemails.IS_READ, Voicemails.SOURCE_PACKAGE, Voicemails.SOURCE_DATA,
66                 Voicemails.HAS_CONTENT, Voicemails.MIME_TYPE};
67         final int ID_INDEX = 0;
68         final int NUMBER_INDEX = 1;
69         final int DATE_INDEX = 2;
70         final int DURATION_INDEX = 3;
71         final int IS_READ_INDEX = 4;
72         final int SOURCE_PACKAGE_INDEX = 5;
73         final int SOURCE_DATA_INDEX = 6;
74         final int HAS_CONTENT_INDEX = 7;
75         final int MIME_TYPE_INDEX = 8;
76 
77         String insertCallsNumber = "0123456789";
78         long insertCallsDuration = 120;
79         String insertSourceData = "internal_id";
80         String insertMimeType = "audio/mp3";
81         long insertDate = 1324478862000L;
82 
83         String updateCallsNumber = "9876543210";
84         long updateCallsDuration = 310;
85         String updateSourceData = "another_id";
86         long updateDate = 1324565262000L;
87 
88         // Test: insert
89         ContentValues value = new ContentValues();
90         value.put(Voicemails.NUMBER, insertCallsNumber);
91         value.put(Voicemails.DATE, insertDate);
92         value.put(Voicemails.DURATION, insertCallsDuration);
93         // Source package is expected to be inserted by the provider, if not set.
94         value.put(Voicemails.SOURCE_DATA, insertSourceData);
95         value.put(Voicemails.MIME_TYPE, insertMimeType);
96         value.put(Voicemails.IS_READ, false);
97         value.put(Voicemails.HAS_CONTENT, true);
98 
99         Uri uri = mVoicemailProvider.insert(mVoicemailContentUri, value);
100         Cursor cursor = mVoicemailProvider.query(
101                 mVoicemailContentUri, VOICEMAILS_PROJECTION,
102                 Voicemails.NUMBER + " = ?",
103                 new String[] {insertCallsNumber}, null, null);
104         assertTrue(cursor.moveToNext());
105         assertEquals(insertCallsNumber, cursor.getString(NUMBER_INDEX));
106         assertEquals(insertDate, cursor.getLong(DATE_INDEX));
107         assertEquals(insertCallsDuration, cursor.getLong(DURATION_INDEX));
108         assertEquals(mSourcePackageName, cursor.getString(SOURCE_PACKAGE_INDEX));
109         assertEquals(insertSourceData, cursor.getString(SOURCE_DATA_INDEX));
110         assertEquals(insertMimeType, cursor.getString(MIME_TYPE_INDEX));
111         assertEquals(0, cursor.getInt(IS_READ_INDEX));
112         assertEquals(1, cursor.getInt(HAS_CONTENT_INDEX));
113         int id = cursor.getInt(ID_INDEX);
114         assertEquals(id, Integer.parseInt(uri.getLastPathSegment()));
115         cursor.close();
116 
117         // Test: update
118         value.clear();
119         value.put(Voicemails.NUMBER, updateCallsNumber);
120         value.put(Voicemails.DATE, updateDate);
121         value.put(Voicemails.DURATION, updateCallsDuration);
122         value.put(Voicemails.SOURCE_DATA, updateSourceData);
123 
124         mVoicemailProvider.update(uri, value, null, null);
125         cursor = mVoicemailProvider.query(mVoicemailContentUri, VOICEMAILS_PROJECTION,
126                 Voicemails._ID + " = " + id, null, null, null);
127         assertEquals(1, cursor.getCount());
128         assertTrue(cursor.moveToNext());
129         assertEquals(mSourcePackageName, cursor.getString(SOURCE_PACKAGE_INDEX));
130         assertEquals(updateCallsNumber, cursor.getString(NUMBER_INDEX));
131         assertEquals(updateDate, cursor.getLong(DATE_INDEX));
132         assertEquals(updateCallsDuration, cursor.getLong(DURATION_INDEX));
133         assertEquals(updateSourceData, cursor.getString(SOURCE_DATA_INDEX));
134         cursor.close();
135 
136         // Test: delete
137         mVoicemailProvider.delete(mVoicemailContentUri, Voicemails._ID + " = " + id, null);
138         cursor = mVoicemailProvider.query(mVoicemailContentUri, VOICEMAILS_PROJECTION,
139                 Voicemails._ID + " = " + id, null, null, null);
140         assertEquals(0, cursor.getCount());
141         cursor.close();
142     }
143 
144     // Data column should be automatically generated during insert.
testInsert_doesNotUpdateDataColumn()145     public void testInsert_doesNotUpdateDataColumn() throws Exception {
146 
147         final String newFilePath = "my/new/file/path";
148         final ContentValues value = buildContentValuesForNewVoicemail();
149         value.put(Voicemails._DATA, newFilePath);
150         mVoicemailProvider.insert(mVoicemailContentUri, value);
151 
152         assertDataNotEquals(newFilePath);
153     }
154 
testDataColumnUpdate_throwsIllegalArgumentException()155     public void testDataColumnUpdate_throwsIllegalArgumentException() throws Exception {
156 
157         final ContentValues value = buildContentValuesForNewVoicemail();
158         final Uri uri = mVoicemailProvider.insert(mVoicemailContentUri, value);
159 
160         // Test: update
161         final String newFilePath = "another/file/path";
162 
163         value.clear();
164         value.put(Voicemails._DATA, newFilePath);
165         try {
166             mVoicemailProvider.update(uri, value, null, null);
167             fail("IllegalArgumentException expected but not thrown.");
168         } catch (IllegalArgumentException e) {
169             // pass
170         }
171 
172         assertDataNotEquals(newFilePath);
173     }
174 
assertDataNotEquals(String newFilePath)175     private void assertDataNotEquals(String newFilePath) throws RemoteException {
176         // Make sure data value is not actually updated.
177         final Cursor cursor = mVoicemailProvider.query(mVoicemailContentUri,
178                 new String[]{Voicemails._DATA}, null, null, null);
179         cursor.moveToNext();
180         final String data = cursor.getString(0);
181         assertFalse(data.equals(newFilePath));
182     }
183 
buildContentValuesForNewVoicemail()184     private ContentValues buildContentValuesForNewVoicemail() {
185         final String insertCallsNumber = "0123456789";
186         final long insertCallsDuration = 120;
187         final String insertSourceData = "internal_id";
188         final String insertMimeType = "audio/mp3";
189         final long insertDate = 1324478862000L;
190 
191         ContentValues value = new ContentValues();
192         value.put(Voicemails.NUMBER, insertCallsNumber);
193         value.put(Voicemails.DATE, insertDate);
194         value.put(Voicemails.DURATION, insertCallsDuration);
195         // Source package is expected to be inserted by the provider, if not set.
196         value.put(Voicemails.SOURCE_DATA, insertSourceData);
197         value.put(Voicemails.MIME_TYPE, insertMimeType);
198         value.put(Voicemails.IS_READ, false);
199         value.put(Voicemails.HAS_CONTENT, true);
200 
201         return value;
202     }
203 
testStatusTable()204     public void testStatusTable() throws Exception {
205         final String[] STATUS_PROJECTION = new String[] {
206                 Status._ID, Status.SOURCE_PACKAGE, Status.CONFIGURATION_STATE,
207                 Status.DATA_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE,
208                 Status.SETTINGS_URI, Status.VOICEMAIL_ACCESS_URI};
209         final int ID_INDEX = 0;
210         final int SOURCE_PACKAGE_INDEX = 1;
211         final int CONFIGURATION_STATE_INDEX = 2;
212         final int DATA_CHANNEL_STATE_INDEX = 3;
213         final int NOTIFICATION_CHANNEL_STATE_INDEX = 4;
214         final int SETTINGS_URI_INDEX = 5;
215         final int VOICEMAIL_ACCESS_URI_INDEX = 6;
216 
217         int insertConfigurationState = Status.CONFIGURATION_STATE_OK;
218         int insertDataChannelState = Status.DATA_CHANNEL_STATE_OK;
219         int insertNotificationChannelState = Status.NOTIFICATION_CHANNEL_STATE_OK;
220         String insertSettingsUri = "settings_uri";
221         String insertVoicemailAccessUri = "tel:901";
222 
223         int updateDataChannelState = Status.DATA_CHANNEL_STATE_NO_CONNECTION;
224         int updateNotificationChannelState = Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
225         String updateSettingsUri = "settings_uri_2";
226 
227         // Test: insert
228         ContentValues value = new ContentValues();
229         value.put(Status.CONFIGURATION_STATE, insertConfigurationState);
230         value.put(Status.DATA_CHANNEL_STATE, insertDataChannelState);
231         value.put(Status.NOTIFICATION_CHANNEL_STATE, insertNotificationChannelState);
232         value.put(Status.SETTINGS_URI, insertSettingsUri);
233         value.put(Status.VOICEMAIL_ACCESS_URI, insertVoicemailAccessUri);
234 
235         Uri uri = mStatusProvider.insert(mStatusContentUri, value);
236         Cursor cursor = mStatusProvider.query(
237                 mStatusContentUri, STATUS_PROJECTION, null, null, null, null);
238         assertTrue(cursor.moveToNext());
239         assertEquals(mSourcePackageName, cursor.getString(SOURCE_PACKAGE_INDEX));
240         assertEquals(insertConfigurationState, cursor.getInt(CONFIGURATION_STATE_INDEX));
241         assertEquals(insertDataChannelState, cursor.getInt(DATA_CHANNEL_STATE_INDEX));
242         assertEquals(insertNotificationChannelState,
243                 cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
244         assertEquals(insertSettingsUri, cursor.getString(SETTINGS_URI_INDEX));
245         assertEquals(insertVoicemailAccessUri, cursor.getString(VOICEMAIL_ACCESS_URI_INDEX));
246         int id = cursor.getInt(ID_INDEX);
247         assertEquals(id, Integer.parseInt(uri.getLastPathSegment()));
248         cursor.close();
249 
250         // Test: update
251         value.clear();
252         value.put(Status.DATA_CHANNEL_STATE, updateDataChannelState);
253         value.put(Status.NOTIFICATION_CHANNEL_STATE, updateNotificationChannelState);
254         value.put(Status.SETTINGS_URI, updateSettingsUri);
255 
256         mStatusProvider.update(uri, value, null, null);
257         cursor = mStatusProvider.query(mStatusContentUri, STATUS_PROJECTION,
258                 Voicemails._ID + " = " + id, null, null, null);
259         assertEquals(1, cursor.getCount());
260         assertTrue(cursor.moveToNext());
261         assertEquals(mSourcePackageName, cursor.getString(SOURCE_PACKAGE_INDEX));
262         assertEquals(updateDataChannelState, cursor.getInt(DATA_CHANNEL_STATE_INDEX));
263         assertEquals(updateNotificationChannelState,
264                 cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
265         assertEquals(updateSettingsUri, cursor.getString(SETTINGS_URI_INDEX));
266         cursor.close();
267 
268         // Test: delete
269         mStatusProvider.delete(mStatusContentUri, Voicemails._ID + " = " + id, null);
270         cursor = mStatusProvider.query(mStatusContentUri, STATUS_PROJECTION,
271                 Voicemails._ID + " = " + id, null, null, null);
272         assertEquals(0, cursor.getCount());
273         cursor.close();
274     }
275 
testVoicemailTablePermissions()276     public void testVoicemailTablePermissions() throws Exception {
277         ContentValues value = new ContentValues();
278         value.put(Voicemails.NUMBER, "0123456789");
279         value.put(Voicemails.SOURCE_PACKAGE, "some.other.package");
280         try {
281             mVoicemailProvider.insert(mVoicemailContentUri, value);
282             fail("Expected SecurityException. None thrown.");
283         } catch (SecurityException e) {
284             // Expected result.
285         }
286     }
287 
testStatusTablePermissions()288     public void testStatusTablePermissions() throws Exception {
289         ContentValues value = new ContentValues();
290         value.put(Status.CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
291         value.put(Status.SOURCE_PACKAGE, "some.other.package");
292         try {
293             mStatusProvider.insert(mStatusContentUri, value);
294             fail("Expected SecurityException. None thrown.");
295         } catch (SecurityException e) {
296             // Expected result.
297         }
298     }
299 }
300