Home | History | Annotate | Download | only in pbapclient
      1 /*
      2  * Copyright (C) 2017 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.bluetooth.pbapclient;
     18 
     19 import android.accounts.Account;
     20 import android.content.Context;
     21 import android.content.pm.PackageManager;
     22 import android.content.res.Resources;
     23 import android.database.Cursor;
     24 import android.net.Uri;
     25 import android.provider.CallLog.Calls;
     26 import android.provider.ContactsContract;
     27 import android.support.test.InstrumentationRegistry;
     28 import android.support.test.filters.MediumTest;
     29 import android.support.test.runner.AndroidJUnit4;
     30 
     31 import com.android.bluetooth.R;
     32 
     33 import org.junit.Assert;
     34 import org.junit.Assume;
     35 import org.junit.Before;
     36 import org.junit.Test;
     37 import org.junit.runner.RunWith;
     38 
     39 import java.io.IOException;
     40 import java.io.InputStream;
     41 import java.util.HashMap;
     42 import java.util.TimeZone;
     43 
     44 @MediumTest
     45 @RunWith(AndroidJUnit4.class)
     46 public class PbapParserTest {
     47     private Account mAccount;
     48     private Resources mTestResources;
     49     private Context mTargetContext;
     50     private static final String TEST_ACCOUNT_NAME = "PBAPTESTACCOUNT";
     51     private static final String TEST_PACKAGE_NAME = "com.android.bluetooth.tests";
     52 
     53     @Before
     54     public void setUp() {
     55         mTargetContext = InstrumentationRegistry.getTargetContext();
     56         Assume.assumeTrue("Ignore test when PbapClientService is not enabled",
     57                 mTargetContext.getResources().getBoolean(R.bool.profile_supported_pbapclient));
     58         mAccount = new Account(TEST_ACCOUNT_NAME,
     59                 mTargetContext.getString(com.android.bluetooth.R.string.pbap_account_type));
     60         try {
     61             mTestResources = mTargetContext.getPackageManager()
     62                     .getResourcesForApplication(TEST_PACKAGE_NAME);
     63         } catch (PackageManager.NameNotFoundException e) {
     64             Assert.fail("Setup Failure Unable to get resources" + e.toString());
     65         }
     66         cleanupCallLog();
     67         cleanupPhonebook();
     68     }
     69 
     70     // testNoTimestamp should parse 1 poorly formed vcard and not crash.
     71     @Test
     72     public void testNoTimestamp() throws IOException {
     73         InputStream fileStream;
     74         fileStream = mTestResources.openRawResource(
     75                 com.android.bluetooth.tests.R.raw.no_timestamp_call_log);
     76         BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
     77                 PbapClientConnectionHandler.VCARD_TYPE_30);
     78         Assert.assertEquals(1, pbapVCardList.getCount());
     79         CallLogPullRequest processor =
     80                 new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
     81                     new HashMap<>(), mAccount);
     82         processor.setResults(pbapVCardList.getList());
     83 
     84         // Verify that these entries aren't in the call log to start.
     85         Assert.assertFalse(verifyCallLog("555-0001", null, "3"));
     86 
     87         // Finish processing the data and verify entries were added to the call log.
     88         processor.onPullComplete();
     89         Assert.assertTrue(verifyCallLog("555-0001", null, "3"));
     90     }
     91 
     92     // testMissedCall should parse one phonecall correctly.
     93     @Test
     94     public void testMissedCall() throws IOException {
     95         InputStream fileStream;
     96         fileStream = mTestResources.openRawResource(
     97                 com.android.bluetooth.tests.R.raw.single_missed_call);
     98         BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
     99                 PbapClientConnectionHandler.VCARD_TYPE_30);
    100         Assert.assertEquals(1, pbapVCardList.getCount());
    101         CallLogPullRequest processor =
    102                 new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
    103                     new HashMap<>(), mAccount);
    104         processor.setResults(pbapVCardList.getList());
    105 
    106         // Verify that these entries aren't in the call log to start.
    107         Assert.assertFalse(verifyCallLog("555-0002", "1483232460000", "3"));
    108         // Finish processing the data and verify entries were added to the call log.
    109         processor.onPullComplete();
    110         Assert.assertTrue(verifyCallLog("555-0002", "1483232460000", "3"));
    111     }
    112 
    113     // testUnknownCall should parse two calls with no phone number.
    114     @Test
    115     public void testUnknownCall() throws IOException {
    116         InputStream fileStream;
    117         fileStream = mTestResources.openRawResource(
    118                 com.android.bluetooth.tests.R.raw.unknown_number_call);
    119         BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
    120                 PbapClientConnectionHandler.VCARD_TYPE_30);
    121         Assert.assertEquals(2, pbapVCardList.getCount());
    122         CallLogPullRequest processor =
    123                 new CallLogPullRequest(mTargetContext, PbapClientConnectionHandler.MCH_PATH,
    124                     new HashMap<>(), mAccount);
    125         processor.setResults(pbapVCardList.getList());
    126 
    127         // Verify that these entries aren't in the call log to start.
    128         Assert.assertFalse(verifyCallLog("", "1483232520000", "3"));
    129         Assert.assertFalse(verifyCallLog("", "1483232580000", "3"));
    130 
    131         // Finish processing the data and verify entries were added to the call log.
    132         processor.onPullComplete();
    133         Assert.assertTrue(verifyCallLog("", "1483232520000", "3"));
    134         Assert.assertTrue(verifyCallLog("", "1483232580000", "3"));
    135     }
    136 
    137     @Test
    138     public void testPullPhoneBook() throws IOException {
    139         InputStream fileStream;
    140         fileStream = mTestResources.openRawResource(
    141                 com.android.bluetooth.tests.R.raw.v30_simple);
    142         BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(mAccount, fileStream,
    143                 PbapClientConnectionHandler.VCARD_TYPE_30);
    144         Assert.assertEquals(1, pbapVCardList.getCount());
    145         PhonebookPullRequest processor = new PhonebookPullRequest(mTargetContext, mAccount);
    146         processor.setResults(pbapVCardList.getList());
    147         Assert.assertFalse(verifyPhonebook("Roid And", "0300000000"));
    148         processor.onPullComplete();
    149         Assert.assertTrue(verifyPhonebook("Roid And", "0300000000"));
    150     }
    151 
    152     private void cleanupCallLog() {
    153         mTargetContext.getContentResolver().delete(Calls.CONTENT_URI, null, null);
    154     }
    155 
    156     private void cleanupPhonebook() {
    157         mTargetContext.getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI,
    158                 null, null);
    159     }
    160 
    161     // Find Entries in call log with type matching number and date.
    162     // If number or date is null it will match any number or date respectively.
    163     private boolean verifyCallLog(String number, String date, String type) {
    164         String[] query = new String[]{Calls.NUMBER, Calls.DATE, Calls.TYPE};
    165         Cursor cursor = mTargetContext.getContentResolver()
    166                 .query(Calls.CONTENT_URI, query, Calls.TYPE + "= " + type, null,
    167                         Calls.DATE + ", " + Calls.NUMBER);
    168         if (date != null) {
    169             date = adjDate(date);
    170         }
    171         if (cursor != null) {
    172             while (cursor.moveToNext()) {
    173                 String foundNumber = cursor.getString(cursor.getColumnIndex(Calls.NUMBER));
    174                 String foundDate = cursor.getString(cursor.getColumnIndex(Calls.DATE));
    175                 if ((number == null || number.equals(foundNumber)) && (date == null || date.equals(
    176                         foundDate))) {
    177                     return true;
    178                 }
    179             }
    180             cursor.close();
    181         }
    182         return false;
    183     }
    184 
    185     // Get time zone from device and adjust date to the device's time zone.
    186     private static String adjDate(String date) {
    187         TimeZone tz = TimeZone.getDefault();
    188         long dt = Long.valueOf(date) - tz.getRawOffset();
    189         return Long.toString(dt);
    190     }
    191 
    192     private boolean verifyPhonebook(String name, String number) {
    193         Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
    194                 Uri.encode(number));
    195         Cursor c = mTargetContext.getContentResolver().query(uri, null, null, null);
    196         if (c != null && c.getCount() > 0) {
    197             c.moveToNext();
    198             String displayName = c.getString(
    199                     c.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
    200             if (displayName.equals(name)) {
    201                 return true;
    202             }
    203         }
    204         return false;
    205     }
    206 
    207 }
    208