Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2016 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.annotation.Nullable;
     20 import android.content.ContentResolver;
     21 import android.content.ContentUris;
     22 import android.content.ContentValues;
     23 import android.content.Context;
     24 import android.database.ContentObserver;
     25 import android.database.Cursor;
     26 import android.net.Uri;
     27 import android.provider.BlockedNumberContract;
     28 import android.provider.BlockedNumberContract.BlockedNumbers;
     29 
     30 import junit.framework.Assert;
     31 
     32 import java.util.ArrayList;
     33 import java.util.concurrent.CountDownLatch;
     34 import java.util.concurrent.TimeUnit;
     35 
     36 /**
     37  * CTS tests for blockednumber provider accessed through {@link BlockedNumberContract}.
     38  */
     39 // To run the tests in this file w/o running all the cts tests:
     40 // make cts
     41 // cts-tradefed
     42 // run cts -m CtsProviderTestCases --test android.provider.cts.BlockedNumberContractTest
     43 public class BlockedNumberContractTest extends TestCaseThatRunsIfTelephonyIsEnabled {
     44     private ContentResolver mContentResolver;
     45     private Context mContext;
     46     private ArrayList<Uri> mAddedUris;
     47 
     48     private static final String[] BLOCKED_NUMBERS_PROJECTION = new String[]{
     49             BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
     50             BlockedNumbers.COLUMN_E164_NUMBER};
     51 
     52     @Override
     53     protected void setUp() throws Exception {
     54         super.setUp();
     55         mContext = getInstrumentation().getContext();
     56         mContentResolver = mContext.getContentResolver();
     57         mAddedUris = new ArrayList<>();
     58     }
     59 
     60     @Override
     61     protected void tearDown() throws Exception {
     62         for (Uri row : mAddedUris) {
     63             mContentResolver.delete(row, null, null);
     64         }
     65         mAddedUris.clear();
     66         setDefaultSmsApp(false);
     67 
     68         super.tearDown();
     69     }
     70 
     71     public void testProviderInteractionsAsRegularApp_fails() {
     72         try {
     73             mAddedUris.add(mContentResolver.insert(
     74                     BlockedNumbers.CONTENT_URI, getContentValues("1234567890")));
     75             fail("Should throw SecurityException");
     76         } catch (SecurityException expected) {
     77         }
     78 
     79         try {
     80             mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
     81             fail("Should throw SecurityException");
     82         } catch (SecurityException expected) {
     83         }
     84 
     85         try {
     86             mContentResolver.update(
     87                     BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
     88             fail("Should throw SecurityException");
     89         } catch (SecurityException expected) {
     90         }
     91 
     92         try {
     93             BlockedNumberContract.isBlocked(mContext, "123");
     94             fail("Should throw SecurityException");
     95         } catch (SecurityException expected) {
     96         }
     97 
     98         try {
     99             BlockedNumberContract.unblock(mContext, "1234567890");
    100             fail("Should throw SecurityException");
    101         } catch (SecurityException expected) {
    102         }
    103 
    104         assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
    105     }
    106 
    107     public void testGetType() throws Exception {
    108         assertEquals(BlockedNumbers.CONTENT_TYPE,
    109                 mContentResolver.getType(BlockedNumbers.CONTENT_URI));
    110         assertEquals(BlockedNumbers.CONTENT_ITEM_TYPE,
    111                 mContentResolver.getType(
    112                         ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 0)));
    113 
    114         assertNull(mContentResolver.getType(BlockedNumberContract.AUTHORITY_URI));
    115     }
    116 
    117     public void testInsertAndBlockCheck_succeeds() throws Exception {
    118         setDefaultSmsApp(true);
    119 
    120         assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
    121 
    122         assertInsertBlockedNumberSucceeds("1234567890", null);
    123         // Attempting to insert a duplicate replaces the existing entry.
    124         assertInsertBlockedNumberSucceeds("1234567890", "+812345678901");
    125         assertInsertBlockedNumberSucceeds("1234567890", null);
    126 
    127         assertTrue(BlockedNumberContract.isBlocked(mContext, "1234567890"));
    128         assertFalse(BlockedNumberContract.isBlocked(mContext, "2234567890"));
    129 
    130         assertInsertBlockedNumberSucceeds("2345678901", "+12345678901");
    131         assertTrue(BlockedNumberContract.isBlocked(mContext, "2345678901"));
    132         assertTrue(BlockedNumberContract.isBlocked(mContext, "+12345678901"));
    133 
    134         assertInsertBlockedNumberSucceeds("1234 (at) abcd.com", null);
    135         assertTrue(BlockedNumberContract.isBlocked(mContext, "1234 (at) abcd.com"));
    136 
    137         assertInsertBlockedNumberSucceeds("2345 (at) abcd.com", null);
    138         assertTrue(BlockedNumberContract.isBlocked(mContext, "2345 (at) abcd.com"));
    139 
    140         assertFalse(BlockedNumberContract.isBlocked(mContext, "9999 (at) abcd.com"));
    141         assertFalse(BlockedNumberContract.isBlocked(mContext, "random string"));
    142     }
    143 
    144     public void testUnblock_succeeds() throws Exception {
    145         setDefaultSmsApp(true);
    146 
    147         // Unblocking non-existent blocked number should return 0.
    148         assertEquals(0, BlockedNumberContract.unblock(mContext, "6501004000"));
    149 
    150         assertInsertBlockedNumberSucceeds("6501004000", null);
    151         assertEquals(1, BlockedNumberContract.unblock(mContext, "6501004000"));
    152         assertFalse(BlockedNumberContract.isBlocked(mContext, "(650)1004000"));
    153 
    154         assertInsertBlockedNumberSucceeds("1234 (at) abcd.com", null);
    155         assertEquals(1, BlockedNumberContract.unblock(mContext, "1234 (at) abcd.com"));
    156         assertFalse(BlockedNumberContract.isBlocked(mContext, "1234 (at) abcd.com"));
    157     }
    158 
    159     public void testInsert_failsWithInvalidInputs() throws Exception {
    160         setDefaultSmsApp(true);
    161 
    162         try {
    163             ContentValues cv = new ContentValues();
    164             cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1234");
    165             mAddedUris.add(mContentResolver.insert(
    166                     ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 1),
    167                     new ContentValues()));
    168             fail("Should throw IllegalArgumentException.");
    169         } catch (IllegalArgumentException expected) {
    170             assertTrue(expected.getMessage().contains("Unsupported URI"));
    171         }
    172 
    173         try {
    174             mAddedUris.add(
    175                     mContentResolver.insert(BlockedNumbers.CONTENT_URI, new ContentValues()));
    176             fail("Should throw IllegalArgumentException.");
    177         } catch (IllegalArgumentException expected) {
    178             assertTrue(expected.getMessage().contains("Missing a required column"));
    179         }
    180 
    181         try {
    182             ContentValues cv = new ContentValues();
    183             cv.put(BlockedNumbers.COLUMN_E164_NUMBER, "+1234");
    184             mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
    185             fail("Should throw IllegalArgumentException.");
    186         } catch (IllegalArgumentException expected) {
    187             assertTrue(expected.getMessage().contains("Missing a required column"));
    188         }
    189 
    190         try {
    191             ContentValues cv = new ContentValues();
    192             cv.put(BlockedNumbers.COLUMN_ID, "1");
    193             mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
    194             fail("Should throw IllegalArgumentException.");
    195         } catch (IllegalArgumentException expected) {
    196             assertTrue(expected.getMessage().contains("must not be specified"));
    197         }
    198     }
    199 
    200     public void testUpdate_isUnsupported() throws  Exception {
    201         setDefaultSmsApp(true);
    202         try {
    203             mContentResolver.update(
    204                     BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
    205             fail("Should throw UnsupportedOperationException");
    206         } catch (UnsupportedOperationException expected) {
    207         }
    208     }
    209 
    210     public void testIsBlocked_returnsFalseForNullAndEmpty() throws Exception {
    211         setDefaultSmsApp(true);
    212         assertFalse(BlockedNumberContract.isBlocked(mContext, null));
    213         assertFalse(BlockedNumberContract.isBlocked(mContext, ""));
    214     }
    215 
    216     public void testDelete() throws Exception {
    217         setDefaultSmsApp(true);
    218 
    219         assertInsertBlockedNumberSucceeds("12345", "+112345");
    220         assertInsertBlockedNumberSucceeds("012345", "+112345");
    221         assertEquals(2,
    222                 mContentResolver.delete(
    223                         BlockedNumbers.CONTENT_URI,
    224                         BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
    225                         new String[] {"+112345"}));
    226 
    227         assertInsertBlockedNumberSucceeds("12345", "");
    228         assertEquals(1,
    229                 mContentResolver.delete(
    230                         BlockedNumbers.CONTENT_URI,
    231                         BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
    232                         new String[] {"12345"}));
    233 
    234         Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
    235         assertEquals(1,
    236                 mContentResolver.delete(
    237                         BlockedNumbers.CONTENT_URI,
    238                         BlockedNumbers.COLUMN_ID + "= ?",
    239                         new String[] {Long.toString(ContentUris.parseId(insertedUri))}));
    240 
    241         insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
    242         assertEquals(1,
    243                 mContentResolver.delete(
    244                         ContentUris.withAppendedId(
    245                                 BlockedNumbers.CONTENT_URI, ContentUris.parseId(insertedUri)),
    246                         null, null));
    247 
    248         insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
    249         assertEquals(1, mContentResolver.delete(insertedUri, null, null));
    250 
    251         assertEquals(0,
    252                 mContentResolver.delete(
    253                         BlockedNumbers.CONTENT_URI,
    254                         BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
    255                         new String[] {"12345"}));
    256     }
    257 
    258     public void testDelete_failsOnInvalidInputs() throws Exception {
    259         setDefaultSmsApp(true);
    260 
    261         try {
    262             mContentResolver.delete(Uri.parse("foobar"), null, null);
    263             fail("Should throw IllegalArgumentException");
    264         } catch (IllegalArgumentException expected) {
    265         }
    266 
    267         Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
    268         try {
    269             mContentResolver.delete(
    270                     insertedUri,
    271                     BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
    272                     new String[] {"+112345"});
    273             fail("Should throw IllegalArgumentException");
    274         } catch (IllegalArgumentException expected) {
    275             assertTrue(expected.getMessage().contains("selection must be null"));
    276         }
    277     }
    278 
    279     public void testProviderNotifiesChangesUsingContentObserver() throws Exception {
    280         setDefaultSmsApp(true);
    281 
    282         Cursor cursor = mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
    283 
    284         final CountDownLatch latch = new CountDownLatch(2);
    285         ContentObserver contentObserver = new ContentObserver(null) {
    286             @Override
    287             public void onChange(boolean selfChange) {
    288                 Assert.assertFalse(selfChange);
    289                 latch.notify();
    290             }
    291         };
    292         cursor.registerContentObserver(contentObserver);
    293 
    294         try {
    295             Uri uri = assertInsertBlockedNumberSucceeds("12345", "");
    296             mContentResolver.delete(uri, null, null);
    297             latch.await(10, TimeUnit.SECONDS);
    298         } catch (Exception e) {
    299             fail(e.toString());
    300         } finally {
    301             cursor.unregisterContentObserver(contentObserver);
    302         }
    303     }
    304 
    305     public void testAccessingNonExistentMethod_fails() throws Exception {
    306         setDefaultSmsApp(true);
    307 
    308         try {
    309             mContext.getContentResolver()
    310                     .call(BlockedNumberContract.AUTHORITY_URI, "nonExistentMethod", "1234", null);
    311             fail("Should throw IllegalArgumentException");
    312         } catch (IllegalArgumentException expected) {
    313             assertTrue(expected.getMessage().contains("Unsupported method"));
    314         }
    315     }
    316 
    317     private Uri assertInsertBlockedNumberSucceeds(
    318             String originalNumber, @Nullable String e164Number) {
    319         ContentValues cv = new ContentValues();
    320         cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
    321         if (e164Number != null) {
    322             cv.put(BlockedNumbers.COLUMN_E164_NUMBER, e164Number);
    323         }
    324         Uri insertedUri = mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv);
    325         mAddedUris.add(insertedUri);
    326 
    327         Cursor cursor = mContentResolver.query(
    328                 BlockedNumbers.CONTENT_URI,
    329                 BLOCKED_NUMBERS_PROJECTION,
    330                 BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
    331                 new String[]{originalNumber},
    332                 null);
    333         assertTrue(cursor.moveToFirst());
    334 
    335         assertEquals(originalNumber, cursor.getString(0));
    336         if (e164Number != null) {
    337             assertEquals(e164Number, cursor.getString(1));
    338         }
    339         cursor.close();
    340         return insertedUri;
    341     }
    342 
    343     private ContentValues getContentValues(String originalNumber) {
    344         ContentValues cv = new ContentValues();
    345         cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
    346         return cv;
    347     }
    348 
    349     private void setDefaultSmsApp(boolean setToSmsApp) throws Exception {
    350         ProviderTestUtils.setDefaultSmsApp(
    351                 setToSmsApp, mContext.getPackageName(), getInstrumentation().getUiAutomation());
    352     }
    353 }
    354