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 com.google.android.mms.ContentType;
     20 import com.google.android.mms.pdu.CharacterSets;
     21 
     22 import android.app.UiAutomation;
     23 import android.content.ContentResolver;
     24 import android.content.ContentUris;
     25 import android.content.ContentValues;
     26 import android.content.Context;
     27 import android.content.pm.PackageManager;
     28 import android.database.Cursor;
     29 import android.net.Uri;
     30 import android.provider.BaseColumns;
     31 import android.provider.Telephony;
     32 import android.util.Log;
     33 
     34 /**
     35  * CTS tests for backup and restore of blocked numbers using local transport.
     36  */
     37 // To run the tests in this file w/o running all the cts tests:
     38 // make cts
     39 // cts-tradefed
     40 // run cts -m CtsProviderTestCases --test android.provider.cts.SmsBackupRestoreTest
     41 public class SmsBackupRestoreTest extends TestCaseThatRunsIfTelephonyIsEnabled {
     42     private static final String TAG = "SmsBackupRestoreTest";
     43     private static final String LOCAL_BACKUP_COMPONENT =
     44             "com.android.localtransport/.LocalTransport";
     45     private static final String TELEPHONY_PROVIDER_PACKAGE = "com.android.providers.telephony";
     46 
     47     private static final String[] smsAddressBody1 = new String[] {"+123" , "sms CTS text"};
     48     private static final String[] smsAddressBody2 = new String[] {"+456" , "sms CTS text 2"};
     49     private static final String[] mmsAddresses = new String[] {"+1223", "+43234234"};
     50     private static final String mmsSubject = "MMS Subject CTS";
     51     private static final String mmsBody = "MMS body CTS";
     52 
     53     private static final String[] ID_PROJECTION = new String[] { BaseColumns._ID };
     54     private static final String[] ID_TEXT_ONLY_PROJECTION = new String[] { BaseColumns._ID,
     55             Telephony.Mms.TEXT_ONLY };
     56     private static final String SMS_SELECTION = Telephony.Sms.ADDRESS + " = ? and "
     57             + Telephony.Sms.BODY + " = ?";
     58 
     59     private static final String MMS_SELECTION = Telephony.Mms.SUBJECT + " = ?";
     60 
     61     private static final String[] MMS_PART_TEXT_PROJECTION = new String[]{Telephony.Mms.Part.TEXT};
     62     private static final String MMS_PART_SELECTION = Telephony.Mms.Part.MSG_ID + " = ?";
     63     private static final String MMS_PART_TEXT_SELECTION = Telephony.Mms.Part.CONTENT_TYPE + " = ?";
     64     private static final String[] MMS_ADDR_PROJECTION = new String[] { Telephony.Mms.Addr.ADDRESS };
     65     private static final String MMS_ADDR_SELECTION = Telephony.Mms.Addr.MSG_ID + " = ?";
     66 
     67     private Context mContext;
     68     private ContentResolver mContentResolver;
     69     private UiAutomation mUiAutomation;
     70     private String mOldTransport;
     71     private boolean mOldBackupEnabled;
     72     private boolean mHasFeature;
     73 
     74     @Override
     75     protected void setUp() throws Exception {
     76         super.setUp();
     77         // Wait for the UI Thread to become idle.
     78         getInstrumentation().waitForIdleSync();
     79         mContext = getInstrumentation().getContext();
     80         mContentResolver = mContext.getContentResolver();
     81         mUiAutomation = getInstrumentation().getUiAutomation();
     82         mHasFeature = isFeatureSupported();
     83         if (mHasFeature) {
     84             ProviderTestUtils.setDefaultSmsApp(true, mContext.getPackageName(), mUiAutomation);
     85             mOldTransport =
     86                     ProviderTestUtils.setBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation);
     87             mOldBackupEnabled = ProviderTestUtils.setBackupEnabled(true, mUiAutomation);
     88             clearMessages();
     89             wipeBackup();
     90         }
     91     }
     92 
     93     @Override
     94     protected void tearDown() throws Exception {
     95         if (mHasFeature) {
     96             wipeBackup();
     97             clearMessages();
     98             ProviderTestUtils.setBackupEnabled(mOldBackupEnabled, mUiAutomation);
     99             ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
    100             ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
    101         }
    102 
    103         super.tearDown();
    104     }
    105 
    106     private boolean isFeatureSupported() throws Exception {
    107         return (ProviderTestUtils.hasBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation)
    108                 && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
    109     }
    110 
    111     private void clearMessages() {
    112         mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody1);
    113         mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody2);
    114         try (Cursor mmsCursor =
    115                      mContentResolver.query(Telephony.Mms.CONTENT_URI, ID_PROJECTION, MMS_SELECTION,
    116                              new String[] {mmsSubject}, null)) {
    117             if (mmsCursor != null && mmsCursor.moveToFirst()) {
    118                 final long mmsId = mmsCursor.getLong(0);
    119                 final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
    120                         .appendPath(String.valueOf(mmsId)).appendPath("part").build();
    121                 mContentResolver.delete(partUri, MMS_PART_SELECTION,
    122                         new String[]{String.valueOf(mmsId)});
    123 
    124                 final Uri addrUri = getMmsAddrUri(mmsId);
    125                 mContentResolver.delete(addrUri, MMS_ADDR_SELECTION,
    126                         new String[]{String.valueOf(mmsId)});
    127             }
    128         }
    129         mContentResolver.delete(Telephony.Mms.CONTENT_URI, MMS_SELECTION, new String[]{mmsSubject});
    130     }
    131 
    132     /**
    133      * Test adds 2 SMS messages, 1 text-only MMS messages and 1 non-text-only, runs backup,
    134      * deletes the messages from the provider, runs restore, check if the messages are in the
    135      * provider (with non-text-only one).
    136      * @throws Exception
    137      */
    138     public void testSmsBackupRestore() throws Exception {
    139         if (!mHasFeature) {
    140             Log.i(TAG, "skipping testSmsBackupRestore");
    141             return;
    142         }
    143 
    144         ContentValues smsContentValues[] = new ContentValues[] {
    145                 createSmsValues(smsAddressBody1),
    146                 createSmsValues(smsAddressBody2)};
    147         Log.i(TAG, "Put 2 SMS into the provider");
    148         mContentResolver.bulkInsert(Telephony.Sms.CONTENT_URI, smsContentValues);
    149 
    150         Log.i(TAG, "Put 1 text MMS into the provider");
    151         addMms(true /*isTextOnly*/, mmsBody, mmsSubject, mmsAddresses);
    152         Log.i(TAG, "Put 1 non-text MMS into the provider");
    153         addMms(false /*isTextOnly*/, mmsBody, mmsSubject, mmsAddresses);
    154 
    155         Log.i(TAG, "Run backup");
    156         ProviderTestUtils.runBackup(TELEPHONY_PROVIDER_PACKAGE, mUiAutomation);
    157         Log.i(TAG, "Delete the messages from the provider");
    158         clearMessages();
    159         Log.i(TAG, "Run restore");
    160         ProviderTestUtils.runRestore(TELEPHONY_PROVIDER_PACKAGE, mUiAutomation);
    161 
    162         Log.i(TAG, "Check the providers for the messages");
    163         assertEquals(1,
    164                 mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody1));
    165         assertEquals(1,
    166                 mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody2));
    167 
    168         try (Cursor mmsCursor = mContentResolver.query(Telephony.Mms.CONTENT_URI,
    169               ID_TEXT_ONLY_PROJECTION, MMS_SELECTION, new String[] {mmsSubject}, null)) {
    170             assertNotNull(mmsCursor);
    171             assertEquals(2, mmsCursor.getCount());
    172             for (mmsCursor.moveToFirst(); !mmsCursor.isAfterLast(); mmsCursor.moveToNext()) {
    173               final long mmsId = mmsCursor.getLong(0);
    174               final long mmsTextOnly = mmsCursor.getLong(1);
    175               assertEquals(mmsTextOnly, 1);
    176               final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
    177                   .appendPath(String.valueOf(mmsId)).appendPath("part").build();
    178               // Check the body.
    179               try (Cursor partCursor = mContentResolver.query(partUri, MMS_PART_TEXT_PROJECTION,
    180                     MMS_PART_TEXT_SELECTION, new String[]{ ContentType.TEXT_PLAIN }, null)) {
    181                 assertNotNull(partCursor);
    182                 assertEquals(1, partCursor.getCount());
    183                 assertTrue(partCursor.moveToFirst());
    184                 assertTrue(partCursor.getString(0).startsWith(mmsBody));
    185               }
    186 
    187               // Check if there are 2 parts (smil and body).
    188               assertEquals(2, mContentResolver.delete(partUri, MMS_PART_SELECTION,
    189                     new String[]{String.valueOf(mmsId)}));
    190 
    191               // Check addresses.
    192               final Uri addrUri = getMmsAddrUri(mmsId);
    193               try (Cursor addrCursor = mContentResolver.query(addrUri, MMS_ADDR_PROJECTION,
    194                     MMS_ADDR_SELECTION, new String[]{String.valueOf(mmsId)}, null)) {
    195                 assertNotNull(addrCursor);
    196                 for (String addr : mmsAddresses) {
    197                   addrCursor.moveToNext();
    198                   assertEquals(addr, addrCursor.getString(0));
    199                 }
    200               }
    201               assertEquals(mmsAddresses.length, mContentResolver.delete(addrUri, MMS_ADDR_SELECTION,
    202                     new String[]{String.valueOf(mmsId)}));
    203             }
    204         }
    205     }
    206 
    207     private static Uri getMmsAddrUri(long mmsId) {
    208         Uri.Builder builder = Telephony.Mms.CONTENT_URI.buildUpon();
    209         builder.appendPath(String.valueOf(mmsId)).appendPath("addr");
    210         return builder.build();
    211     }
    212 
    213     private void addMms(boolean isTextOnly, String body, String subject, String[] addresses) {
    214         // Insert mms.
    215         final ContentValues mmsValues = new ContentValues(2);
    216         mmsValues.put(Telephony.Mms.TEXT_ONLY, isTextOnly ? 1 : 0);
    217         mmsValues.put(Telephony.Mms.MESSAGE_TYPE, 128);
    218         mmsValues.put(Telephony.Mms.SUBJECT, subject);
    219         final Uri mmsUri = mContentResolver.insert(Telephony.Mms.CONTENT_URI, mmsValues);
    220         assertNotNull(mmsUri);
    221         final long mmsId = ContentUris.parseId(mmsUri);
    222 
    223         final String srcName = String.format("text.%06d.txt", 0);
    224         // Insert body part.
    225         final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon()
    226                 .appendPath(String.valueOf(mmsId)).appendPath("part").build();
    227 
    228         final ContentValues values = new ContentValues(8);
    229         values.put(Telephony.Mms.Part.MSG_ID, mmsId);
    230         values.put(Telephony.Mms.Part.SEQ, 0);
    231         values.put(Telephony.Mms.Part.CONTENT_TYPE, ContentType.TEXT_PLAIN);
    232         values.put(Telephony.Mms.Part.NAME, srcName);
    233         values.put(Telephony.Mms.Part.CONTENT_ID, "<"+srcName+">");
    234         values.put(Telephony.Mms.Part.CONTENT_LOCATION, srcName);
    235         values.put(Telephony.Mms.Part.CHARSET, CharacterSets.DEFAULT_CHARSET);
    236         if (!isTextOnly) {
    237             body = body + " Non text-only";
    238         }
    239         values.put(Telephony.Mms.Part.TEXT, body);
    240         mContentResolver.insert(partUri, values);
    241 
    242         // Insert addresses.
    243         final Uri addrUri = Uri.withAppendedPath(mmsUri, "addr");
    244         for (int i = 0; i < addresses.length; ++i) {
    245             ContentValues addrValues = new ContentValues(3);
    246             addrValues.put(Telephony.Mms.Addr.TYPE, i);
    247             addrValues.put(Telephony.Mms.Addr.CHARSET, CharacterSets.DEFAULT_CHARSET);
    248             addrValues.put(Telephony.Mms.Addr.ADDRESS, addresses[i]);
    249             addrValues.put(Telephony.Mms.Addr.MSG_ID, mmsId);
    250             mContentResolver.insert(addrUri, addrValues);
    251         }
    252     }
    253 
    254     private static ContentValues createSmsValues(String[] addressBody) {
    255         ContentValues smsRow = new ContentValues();
    256         smsRow.put(Telephony.Sms.ADDRESS, addressBody[0]);
    257         smsRow.put(Telephony.Sms.BODY, addressBody[1]);
    258         return smsRow;
    259     }
    260 
    261     private void wipeBackup() throws Exception {
    262         ProviderTestUtils.wipeBackup(LOCAL_BACKUP_COMPONENT, TELEPHONY_PROVIDER_PACKAGE,
    263                 mUiAutomation);
    264     }
    265 }
    266