OSDN Git Service

PBAP Client Call Log
authorJoseph Pirozzo <pirozzoj@google.com>
Wed, 5 Apr 2017 21:38:17 +0000 (14:38 -0700)
committerJoseph Pirozzo <pirozzoj@google.com>
Mon, 17 Apr 2017 17:25:03 +0000 (10:25 -0700)
Update PBAP Client to correctly handle cases where a call log has either
an unknown phone number or missing timestamp.  Included are test cases
to verify proper parsing.

Bug: 26760364
Bug: 29230296

Test: runtest bluetooth -c com.android.bluetooth.pbapclient.PbapParserTest
Change-Id: Ibdabd0320f3bdd6dee0d7bd7b5ddd9400219f3d4
(cherry picked from commit e1ee0dace9e715e3d94339dc642b8767db83b89e)

src/com/android/bluetooth/pbapclient/CallLogPullRequest.java
tests/res/raw/no_timestamp_call_log.vcf [new file with mode: 0644]
tests/res/raw/single_missed_call.vcf [new file with mode: 0644]
tests/res/raw/unknown_number_call.vcf [new file with mode: 0644]
tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java [new file with mode: 0644]

index 08fcc90..132d010 100644 (file)
@@ -75,36 +75,34 @@ public class CallLogPullRequest extends PullRequest {
 
             ArrayList<ContentProviderOperation> ops = new ArrayList<>();
             for (VCardEntry vcard : mEntries) {
+                ContentValues values = new ContentValues();
+
+                values.put(CallLog.Calls.TYPE, type);
+
                 List<PhoneData> phones = vcard.getPhoneList();
-                if (phones == null || phones.size() != 1) {
-                    if (VDBG) {
-                        Log.d(TAG, "Incorrect number of phones: " + vcard);
-                    }
-                    continue;
+                if (phones == null || phones.get(0).getNumber().equals(";")) {
+                    values.put(CallLog.Calls.NUMBER, "");
+                } else {
+                    values.put(CallLog.Calls.NUMBER, phones.get(0).getNumber());
                 }
 
                 List<Pair<String, String>> irmc = vcard.getUnknownXData();
-                Date date = null;
                 SimpleDateFormat parser = new SimpleDateFormat(TIMESTAMP_FORMAT);
-                for (Pair<String, String> pair : irmc) {
-                    if (pair.first.startsWith(TIMESTAMP_PROPERTY)) {
-                        try {
-                            date = parser.parse(pair.second);
-                        } catch (ParseException e) {
-                            Log.d(TAG, "Failed to parse date ");
-                            if (VDBG) {
-                                Log.d(TAG, pair.second);
+                if (irmc != null) {
+                    for (Pair<String, String> pair : irmc) {
+                        if (pair.first.startsWith(TIMESTAMP_PROPERTY)) {
+                            try {
+                                values.put(CallLog.Calls.DATE, parser.parse(pair.second).getTime());
+                            } catch (ParseException e) {
+                                Log.d(TAG, "Failed to parse date ");
+                                if (VDBG) {
+                                    Log.d(TAG, pair.second);
+                                }
                             }
                         }
                     }
                 }
 
-                ContentValues values = new ContentValues();
-                values.put(CallLog.Calls.TYPE, type);
-                values.put(CallLog.Calls.NUMBER, phones.get(0).getNumber());
-                if (date != null) {
-                    values.put(CallLog.Calls.DATE, date.getTime());
-                }
                 ops.add(ContentProviderOperation.newInsert(CallLog.Calls.CONTENT_URI)
                         .withValues(values).withYieldAllowed(true).build());
             }
diff --git a/tests/res/raw/no_timestamp_call_log.vcf b/tests/res/raw/no_timestamp_call_log.vcf
new file mode 100644 (file)
index 0000000..1d30ab2
--- /dev/null
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+VERSION:3.0
+FN:
+N:
+TEL;TYPE=0:555-0001
+END:VCARD
diff --git a/tests/res/raw/single_missed_call.vcf b/tests/res/raw/single_missed_call.vcf
new file mode 100644 (file)
index 0000000..9c36e9f
--- /dev/null
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+VERSION:3.0
+FN:
+N:
+TEL;TYPE=0:555-0002
+X-IRMC-CALL-DATETIME;TYPE=RECEIVED:20170101T010100
+END:VCARD
diff --git a/tests/res/raw/unknown_number_call.vcf b/tests/res/raw/unknown_number_call.vcf
new file mode 100644 (file)
index 0000000..76975cf
--- /dev/null
@@ -0,0 +1,14 @@
+BEGIN:VCARD
+VERSION:3.0
+FN:
+N:
+TEL;TYPE=0:
+X-IRMC-CALL-DATETIME;TYPE=RECEIVED:20170101T010200
+END:VCARD
+BEGIN:VCARD
+VERSION:3.0
+FN:
+N:
+TEL;TYPE=0:Unknown
+X-IRMC-CALL-DATETIME;TYPE=RECEIVED:20170101T010300
+END:VCARD
diff --git a/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java b/tests/src/com/android/bluetooth/pbapclient/PbapParserTest.java
new file mode 100644 (file)
index 0000000..5007238
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.pbapclient;
+
+import android.accounts.Account;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.provider.CallLog.Calls;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PbapParserTest extends AndroidTestCase {
+    private Account mAccount;
+    private Resources testResources;
+    private static final String mTestAccountName = "PBAPTESTACCOUNT";
+    private static final String mTestPackageName = "com.android.bluetooth.tests";
+
+    @Before
+    public void setUp() {
+        mAccount = new Account(mTestAccountName,
+                mContext.getString(com.android.bluetooth.R.string.pbap_account_type));
+        try {
+            testResources =
+                    mContext.getPackageManager().getResourcesForApplication(mTestPackageName);
+        } catch (Exception e) {
+            fail("Setup Failure Unable to get resources" + e.toString());
+        }
+    }
+
+    // testNoTimestamp should parse 1 poorly formed vcard and not crash.
+    @Test
+    public void testNoTimestamp() throws IOException {
+        InputStream fileStream;
+        fileStream = testResources.openRawResource(
+                com.android.bluetooth.tests.R.raw.no_timestamp_call_log);
+        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(
+                mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
+        assertEquals(1, pbapVCardList.getCount());
+        CallLogPullRequest processor =
+                new CallLogPullRequest(mContext, PbapClientConnectionHandler.MCH_PATH);
+        processor.setResults(pbapVCardList.getList());
+
+        // Verify that these entries aren't in the call log to start.
+        assertFalse(verifyCallLog("555-0001", null, "3"));
+
+        // Finish processing the data and verify entries were added to the call log.
+        processor.onPullComplete();
+        assertTrue(verifyCallLog("555-0001", null, "3"));
+    }
+
+    // testMissedCall should parse one phonecall correctly.
+    @Test
+    public void testMissedCall() throws IOException {
+        InputStream fileStream;
+        fileStream =
+                testResources.openRawResource(com.android.bluetooth.tests.R.raw.single_missed_call);
+        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(
+                mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
+        assertEquals(1, pbapVCardList.getCount());
+        CallLogPullRequest processor =
+                new CallLogPullRequest(mContext, PbapClientConnectionHandler.MCH_PATH);
+        processor.setResults(pbapVCardList.getList());
+
+        // Verify that these entries aren't in the call log to start.
+        assertFalse(verifyCallLog("555-0002", "1483232460000", "3"));
+
+        // Finish processing the data and verify entries were added to the call log.
+        processor.onPullComplete();
+        assertTrue(verifyCallLog("555-0002", "1483232460000", "3"));
+    }
+
+    // testUnknownCall should parse two calls with no phone number.
+    @Test
+    public void testUnknownCall() throws IOException {
+        InputStream fileStream;
+        fileStream = testResources.openRawResource(
+                com.android.bluetooth.tests.R.raw.unknown_number_call);
+        BluetoothPbapVcardList pbapVCardList = new BluetoothPbapVcardList(
+                mAccount, fileStream, PbapClientConnectionHandler.VCARD_TYPE_30);
+        assertEquals(2, pbapVCardList.getCount());
+        CallLogPullRequest processor =
+                new CallLogPullRequest(mContext, PbapClientConnectionHandler.MCH_PATH);
+        processor.setResults(pbapVCardList.getList());
+
+        // Verify that these entries aren't in the call log to start.
+        assertFalse(verifyCallLog("", "1483232520000", "3"));
+        assertFalse(verifyCallLog("", "1483232580000", "3"));
+
+        // Finish processing the data and verify entries were added to the call log.
+        processor.onPullComplete();
+        assertTrue(verifyCallLog("", "1483232520000", "3"));
+        assertTrue(verifyCallLog("", "1483232580000", "3"));
+    }
+
+    // Find Entries in call log with type matching number and date.
+    // If number or date is null it will match any number or date respectively.
+    boolean verifyCallLog(String number, String date, String type) {
+        String[] query = new String[] {Calls.NUMBER, Calls.DATE, Calls.TYPE};
+        Cursor cursor = mContext.getContentResolver().query(Calls.CONTENT_URI, query,
+                Calls.TYPE + "= " + type, null, Calls.DATE + ", " + Calls.NUMBER);
+        if (cursor != null) {
+            while (cursor.moveToNext()) {
+                String foundNumber = cursor.getString(cursor.getColumnIndex(Calls.NUMBER));
+                String foundDate = cursor.getString(cursor.getColumnIndex(Calls.DATE));
+                if ((number == null || number.equals(foundNumber))
+                        && (date == null || date.equals(foundDate))) {
+                    return true;
+                }
+            }
+            cursor.close();
+        }
+        return false;
+    }
+}