• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 package com.android.cellbroadcastreceiver.unit;
17 
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.Mockito.doReturn;
20 import static com.google.common.truth.Truth.assertThat;
21 import static org.mockito.Mockito.times;
22 import static org.mockito.Mockito.verify;
23 
24 import android.content.ContentProvider;
25 import android.content.ContentValues;
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.content.res.Configuration;
29 import android.content.res.Resources;
30 import android.database.Cursor;
31 import android.net.Uri;
32 import android.os.UserManager;
33 import android.provider.Telephony.CellBroadcasts;
34 import android.telephony.SmsCbCmasInfo;
35 import android.telephony.SmsCbEtwsInfo;
36 import android.telephony.SmsCbLocation;
37 import android.telephony.SmsCbMessage;
38 import android.telephony.SubscriptionManager;
39 import android.test.mock.MockContentResolver;
40 import android.test.mock.MockContext;
41 import android.util.Log;
42 import com.android.cellbroadcastreceiver.CellBroadcastDatabaseHelper;
43 import junit.framework.TestCase;
44 import org.junit.Test;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 
48 public class CellBroadcastContentProviderTest extends TestCase {
49     private static final String TAG = CellBroadcastContentProviderTest.class.getSimpleName();
50 
51     public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts-app");
52 
53     private static final int GEO_SCOPE = 1;
54     private static final String PLMN = "123456";
55     private static final int LAC = 13;
56     private static final int CID = 123;
57     private static final int SERIAL_NUMBER = 17984;
58     private static final int SERVICE_CATEGORY = 4379;
59     private static final String LANGUAGE_CODE = "en";
60     private static final String MESSAGE_BODY = "AMBER Alert: xxxx";
61     private static final int MESSAGE_FORMAT = 1;
62     private static final int MESSAGE_PRIORITY = 3;
63     private static final int ETWS_WARNING_TYPE = 1;
64     private static final int CMAS_MESSAGE_CLASS = 1;
65     private static final int CMAS_CATEGORY = 6;
66     private static final int CMAS_RESPONSE_TYPE = 1;
67     private static final int CMAS_SEVERITY = 2;
68     private static final int CMAS_URGENCY = 3;
69     private static final int CMAS_CERTAINTY = 4;
70 
71     private CellBroadcastContentProviderTestable mCellBroadcastProviderTestable;
72     private MockContextWithProvider mContext;
73     private MockContentResolver mContentResolver;
74     @Mock
75     UserManager mUserManager;
76     @Mock
77     SubscriptionManager mSubManager;
78     @Mock
79     ContentProvider mMockSmsProvider;
80     @Mock
81     Resources mMockResource;
82     @Mock
83     Context mMockContext;
84 
85     @Override
setUp()86     protected void setUp() throws Exception {
87         super.setUp();
88         MockitoAnnotations.initMocks(this);
89 
90         mCellBroadcastProviderTestable = new CellBroadcastContentProviderTestable();
91         mContext = new MockContextWithProvider(mCellBroadcastProviderTestable);
92         mContentResolver = mContext.getContentResolver();
93     }
94 
95     @Override
tearDown()96     protected void tearDown() throws Exception {
97         mCellBroadcastProviderTestable.closeDatabase();
98         super.tearDown();
99     }
100 
101     @Test
102     @InstrumentationTest
103     // This test requires the content provider from the cell broadcast module, so it is disabled for
104     // OEM testing because it is not a true unit test
testInsert()105     public void testInsert() {
106         try {
107             ContentValues msg = new ContentValues();
108             msg.put(CellBroadcasts.SERIAL_NUMBER, SERIAL_NUMBER);
109             mContentResolver.insert(CONTENT_URI, msg);
110             fail();
111         } catch (UnsupportedOperationException ex) {
112             // pass the test
113         }
114     }
115 
116     @Test
117     @InstrumentationTest
118     // This test requires the content provider from the cell broadcast module, so it is disabled for
119     // OEM testing because it is not a true unit test
testDelete()120     public void testDelete() {
121         try {
122             mContentResolver.delete(CONTENT_URI, null, null);
123             fail();
124         } catch (UnsupportedOperationException ex) {
125             // pass the test
126         }
127     }
128 
129     @Test
130     @InstrumentationTest
131     // This test requires the content provider from the cell broadcast module, so it is disabled for
132     // OEM testing because it is not a true unit test
testUpdate()133     public void testUpdate() {
134         try {
135             mContentResolver.update(CONTENT_URI, null, null);
136             fail();
137         } catch (UnsupportedOperationException ex) {
138             // pass the test
139         }
140     }
141 
142     @Test
143     @InstrumentationTest
144     // This test requires the content provider from the cell broadcast module, so it is disabled for
145     // OEM testing because it is not a true unit test
testDeleteAll()146     public void testDeleteAll() {
147         // Insert a cell broadcast message
148         mCellBroadcastProviderTestable.insertNewBroadcast(fakeSmsCbMessage());
149         // Verify that the record is inserted into the database correctly.
150         Cursor cursor = mContentResolver.query(CONTENT_URI,
151                 CellBroadcastDatabaseHelper.QUERY_COLUMNS, null, null, null);
152         assertThat(cursor.getCount()).isEqualTo(1);
153         // delete all
154         mCellBroadcastProviderTestable.deleteAllBroadcasts();
155         cursor = mContentResolver.query(CONTENT_URI, CellBroadcastDatabaseHelper.QUERY_COLUMNS,
156                 null, null, null);
157         assertThat(cursor.getCount()).isEqualTo(0);
158     }
159 
160     @Test
161     @InstrumentationTest
162     // This test requires the content provider from the cell broadcast module, so it is disabled for
163     // OEM testing because it is not a true unit test
testDeleteBroadcast()164     public void testDeleteBroadcast() {
165         // Insert two cell broadcast message
166         mCellBroadcastProviderTestable.insertNewBroadcast(fakeSmsCbMessage());
167         mCellBroadcastProviderTestable.insertNewBroadcast(fakeSmsCbMessage());
168         // Verify that the record is inserted into the database correctly.
169         Cursor cursor = mContentResolver.query(CONTENT_URI,
170                 CellBroadcastDatabaseHelper.QUERY_COLUMNS, null, null, null);
171         assertThat(cursor.getCount()).isEqualTo(2);
172         // delete one message
173         mCellBroadcastProviderTestable.deleteBroadcast(1);
174         cursor = mContentResolver.query(CONTENT_URI, CellBroadcastDatabaseHelper.QUERY_COLUMNS,
175                 null, null, null);
176         assertThat(cursor.getCount()).isEqualTo(1);
177     }
178 
179     @Test
180     @InstrumentationTest
testMarkSmsSyncPending()181     public void testMarkSmsSyncPending() {
182         SmsCbMessage msg = fakeSmsCbMessage();
183         long deliveryTime = msg.getReceivedTime();
184         mCellBroadcastProviderTestable.insertNewBroadcast(msg);
185         // Verify that there is no record with smsSyncPending set
186         Cursor cursor = mContentResolver.query(CONTENT_URI,
187                 CellBroadcastDatabaseHelper.QUERY_COLUMNS,
188                 CellBroadcastDatabaseHelper.SMS_SYNC_PENDING + "=1" , null, null);
189         assertThat(cursor.getCount()).isEqualTo(0);
190         mCellBroadcastProviderTestable.markBroadcastSmsSyncPending(
191                 CellBroadcasts.DELIVERY_TIME,
192                 deliveryTime, true);
193         cursor = mContentResolver.query(CONTENT_URI,
194                 CellBroadcastDatabaseHelper.QUERY_COLUMNS,
195                 CellBroadcastDatabaseHelper.SMS_SYNC_PENDING + "=1" , null, null);
196         assertThat(cursor.getCount()).isEqualTo(1);
197     }
198 
199     @Test
200     @InstrumentationTest
testWriteSmsInboxBeforeUserUnlock()201     public void testWriteSmsInboxBeforeUserUnlock() {
202         doReturn(false).when(mUserManager).isUserUnlocked();
203         doReturn(true).when(mUserManager).isSystemUser();
204         SmsCbMessage msg = fakeSmsCbMessage();
205         mCellBroadcastProviderTestable.insertNewBroadcast(msg);
206         // verify does not write message to SMS db
207         mCellBroadcastProviderTestable.writeMessageToSmsInbox(msg, mContext);
208         // Verify that there is a record with smsSyncPending set
209         Cursor cursor = mContentResolver.query(CONTENT_URI,
210                 CellBroadcastDatabaseHelper.QUERY_COLUMNS,
211                 CellBroadcastDatabaseHelper.SMS_SYNC_PENDING + "=1" , null, null);
212         assertThat(cursor.getCount()).isEqualTo(1);
213         verify(mMockSmsProvider, times(0)).insert(any(), any());
214     }
215 
216     @Test
217     @InstrumentationTest
testWriteSmsInboxNonSystemUser()218     public void testWriteSmsInboxNonSystemUser() {
219         doReturn(false).when(mUserManager).isSystemUser();
220         SmsCbMessage msg = fakeSmsCbMessage();
221         // verify does not write message to SMS db
222         mCellBroadcastProviderTestable.writeMessageToSmsInbox(msg, mContext);
223         verify(mMockSmsProvider, times(0)).insert(any(), any());
224     }
225 
226     @Test
227     @InstrumentationTest
228     // This test requires the content provider from the cell broadcast module, so it is disabled for
229     // OEM testing because it is not a true unit test
testInsertQuery()230     public void testInsertQuery() {
231         // Insert a cell broadcast message
232         mCellBroadcastProviderTestable.insertNewBroadcast(fakeSmsCbMessage());
233 
234         // Verify that the record is inserted into the database correctly.
235         Cursor cursor = mContentResolver.query(CONTENT_URI,
236                 CellBroadcastDatabaseHelper.QUERY_COLUMNS, null, null, null);
237         assertThat(cursor.getCount()).isEqualTo(1);
238 
239         cursor.moveToNext();
240         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE)))
241                 .isEqualTo(GEO_SCOPE);
242         assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.PLMN)))
243                 .isEqualTo(PLMN);
244         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.LAC))).isEqualTo(LAC);
245         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CID))).isEqualTo(CID);
246         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER)))
247                 .isEqualTo(SERIAL_NUMBER);
248         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY)))
249                 .isEqualTo(SERVICE_CATEGORY);
250         assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE)))
251                 .isEqualTo(LANGUAGE_CODE);
252         assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY)))
253                 .isEqualTo(MESSAGE_BODY);
254         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY)))
255                 .isEqualTo(MESSAGE_PRIORITY);
256         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.ETWS_WARNING_TYPE)))
257                 .isEqualTo(ETWS_WARNING_TYPE);
258         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_MESSAGE_CLASS)))
259                 .isEqualTo(CMAS_MESSAGE_CLASS);
260         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CATEGORY)))
261                 .isEqualTo(CMAS_CATEGORY);
262         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_RESPONSE_TYPE)))
263                 .isEqualTo(CMAS_RESPONSE_TYPE);
264         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_SEVERITY)))
265                 .isEqualTo(CMAS_SEVERITY);
266         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_URGENCY)))
267                 .isEqualTo(CMAS_URGENCY);
268         assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CERTAINTY)))
269                 .isEqualTo(CMAS_CERTAINTY);
270     }
271 
272     /**
273      * This is used to give the CellBroadcastContentProviderTest a mocked context which takes a
274      * CellBroadcastProvider and attaches it to the ContentResolver.
275      */
276     private class MockContextWithProvider extends MockContext {
277         private final MockContentResolver mResolver;
278 
MockContextWithProvider(CellBroadcastContentProviderTestable cellBroadcastProvider)279         MockContextWithProvider(CellBroadcastContentProviderTestable cellBroadcastProvider) {
280             mResolver = new MockContentResolver();
281             cellBroadcastProvider.initializeForTesting(this);
282 
283             // Add given cellBroadcastProvider to mResolver, so that mResolver can send queries
284             // to the provider.
285             mResolver.addProvider("cellbroadcasts-app", cellBroadcastProvider);
286         }
287 
288         @Override
getResources()289         public Resources getResources() {
290             return mMockResource;
291         }
292 
293         @Override
createConfigurationContext(Configuration overrideConfiguration)294         public Context createConfigurationContext(Configuration overrideConfiguration) {
295             return mMockContext;
296         }
297 
298         @Override
getContentResolver()299         public MockContentResolver getContentResolver() {
300             return mResolver;
301         }
302 
303 
304         @Override
getSystemService(String name)305         public Object getSystemService(String name) {
306             switch(name) {
307                 case Context.USER_SERVICE:
308                     return mUserManager;
309                 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
310                     return mSubManager;
311                 default:
312                     Log.d(TAG, "getSystemService: returning null");
313                     return null;
314             }
315         }
316 
317         @Override
checkCallingOrSelfPermission(String permission)318         public int checkCallingOrSelfPermission(String permission) {
319             return PackageManager.PERMISSION_GRANTED;
320         }
321     }
322 
fakeSmsCbMessage()323     private SmsCbMessage fakeSmsCbMessage() {
324         return new SmsCbMessage(MESSAGE_FORMAT, GEO_SCOPE, SERIAL_NUMBER,
325                 new SmsCbLocation(PLMN, LAC, CID), SERVICE_CATEGORY, LANGUAGE_CODE, 0 ,
326                 MESSAGE_BODY, MESSAGE_PRIORITY, new SmsCbEtwsInfo(ETWS_WARNING_TYPE, false,
327                 false, false, null),
328                 new SmsCbCmasInfo(CMAS_MESSAGE_CLASS, CMAS_CATEGORY, CMAS_RESPONSE_TYPE,
329                         CMAS_SEVERITY, CMAS_URGENCY, CMAS_CERTAINTY), 0, null,
330                 System.currentTimeMillis(), 1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
331     }
332  }
333