Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c6add3b authored by Tony Mak's avatar Tony Mak Committed by Android (Google) Code Review
Browse files

Merge "Add unit test for commit "Support work contacts in HFP, PBAP, MAP"" into mnc-dev

parents b5f4f864 5bcccbce
Loading
Loading
Loading
Loading
+59 −50
Original line number Diff line number Diff line
@@ -409,42 +409,26 @@ public class BluetoothPbapVcardManager {
            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }

        final MatrixCursor selectionCursor = new MatrixCursor(new String[] {
            Phone.CONTACT_ID
        });

        final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext);
        Cursor contactCursor = null;
        Cursor contactIdCursor = new MatrixCursor(new String[] {
            Phone.CONTACT_ID
        });
        try {
            contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE,
                    null, Phone.CONTACT_ID);
            if (contactCursor != null) {
                final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID);
                long previousContactId = -1;
                // As startPoint, endPoint index starts from 1 to n, we set
                // currentPoint base as 1 not 0
                int currentPoint = 1;
                while(contactCursor.moveToNext() && currentPoint <= endPoint) {
                    long currentContactId = contactCursor.getLong(contactIdColumn);
                    if (previousContactId != currentContactId) {
                        previousContactId = currentContactId;
                        if (currentPoint >= startPoint) {
                            selectionCursor.addRow(new Long[] {currentContactId});
                            if (V) Log.v(TAG, "SelectionCursor addrow: " + currentContactId);
                        }
                        currentPoint++;
                    }
                }
                contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint,
                        endPoint);
            }
        } catch (CursorWindowAllocationException e) {
            Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards");
        } finally {
            if (contactCursor != null) {
                contactCursor.close();
                contactCursor = null;
            }
        }
        return composeContactsAndSendVCards(op, selectionCursor, vcardType21, ownerVCard,
        return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard,
                ignorefilter, filter);
    }

@@ -456,46 +440,72 @@ public class BluetoothPbapVcardManager {
            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }
        final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext);

        Cursor contactCursor = null;
        Cursor contactIdCursor = new MatrixCursor(new String[] {
            Phone.CONTACT_ID
        });
        try {
            contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION,
                    CLAUSE_ONLY_VISIBLE, null, Phone.CONTACT_ID);
            contactIdCursor = ContactCursorFilter.filterByOffset(contactCursor, offset);

        } catch (CursorWindowAllocationException e) {
            Log.e(TAG,
                    "CursorWindowAllocationException while composing phonebook one vcard");
        } finally {
            if (contactCursor != null) {
                contactCursor.close();
                contactCursor = null;
            }
        }
        long targetContactId = 0;
        return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard,
                ignorefilter, filter);
    }

    /**
     * Filter contact cursor by certain condition.
     */
    public static final class ContactCursorFilter {
        /**
         *
         * @param contactCursor
         * @param offset
         * @return a cursor containing contact id of {@code offset} contact.
         */
        public static Cursor filterByOffset(Cursor contactCursor, int offset) {
            return filterByRange(contactCursor, offset, offset);
        }

        /**
         *
         * @param contactCursor
         * @param startPoint
         * @param endPoint
         * @return a cursor containing contact ids of {@code startPoint}th to {@code endPoint}th
         * contact.
         */
        public static Cursor filterByRange(Cursor contactCursor, int startPoint, int endPoint) {
            final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID);
            long previousContactId = -1;
        // As offset starts from 1, currentOffset's base is 1 also
            // As startPoint, endOffset index starts from 1 to n, we set
            // currentPoint base as 1 not 0
            int currentOffset = 1;
        final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID);

        while(contactCursor.moveToNext()) {
            final MatrixCursor contactIdsCursor = new MatrixCursor(new String[]{
                    Phone.CONTACT_ID
            });
            while (contactCursor.moveToNext() && currentOffset <= endPoint) {
                long currentContactId = contactCursor.getLong(contactIdColumn);
                if (previousContactId != currentContactId) {
                if (currentOffset == offset) {
                    targetContactId = currentContactId;
                    break;
                    previousContactId = currentContactId;
                    if (currentOffset >= startPoint) {
                        contactIdsCursor.addRow(new Long[]{currentContactId});
                        if (V) Log.v(TAG, "contactIdsCursor.addRow: " + currentContactId);
                    }
                    currentOffset++;
                previousContactId = currentContactId;
                }
            }

        MatrixCursor contactIdCursor = new MatrixCursor(new String[] {
            Phone.CONTACT_ID
        });
        contactIdCursor.addRow(new Long[] {
            targetContactId
        });

        return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard,
            ignorefilter, filter);
            return contactIdsCursor;
        }
    }

    /**
@@ -511,7 +521,6 @@ public class BluetoothPbapVcardManager {
            } else {
                return new VCardComposer.RawContactEntitlesInfo(RawContactsEntity.CONTENT_URI, contactId);
            }

        }
    }

+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.tests.mock;


import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.test.mock.MockContext;

/**
 * A context that return our {@link android.test.mock.MockContentResolver}.
 */
public class BluetoothMockContext extends MockContext {
    private ContentResolver mMockContentResolver;
    private Context mOriginalContext;

    public BluetoothMockContext(ContentResolver mockContentResolver, Context originalContext) {
        mMockContentResolver = mockContentResolver;
        mOriginalContext = originalContext;
    }

    @Override
    public ContentResolver getContentResolver() {
        return mMockContentResolver;
    }

    @Override
    public Resources getResources() {
        return mOriginalContext.getResources();
    }

    @Override
    public Object getSystemService(String name) {
        return mOriginalContext.getSystemService(name);
    }
}
 No newline at end of file
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.tests.mock;


import android.database.Cursor;
import android.net.Uri;
import android.test.mock.MockContentProvider;

/**
 * A provider that always return the result you want it to return
 */
public class SimpleMockContentProvider extends MockContentProvider {
    private Cursor mResult;

    public SimpleMockContentProvider(Cursor result) {
        mResult = result;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        return mResult;
    }
}
 No newline at end of file
+132 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.tests.pbap;

import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.ContactsContract;
import android.test.AndroidTestCase;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;

import com.android.bluetooth.pbap.BluetoothPbapObexServer;
import com.android.bluetooth.pbap.BluetoothPbapVcardManager;
import com.android.bluetooth.tests.mock.BluetoothMockContext;
import com.android.bluetooth.tests.mock.SimpleMockContentProvider;

import java.util.ArrayList;

public class BluetoothPhabVcardManagerTest extends AndroidTestCase {

    public void testGetContactNamesByNumber() {
        MatrixCursor mc = new MatrixCursor(
                new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        mc.addRow(new Object[]{1L, "A"});
        mc.addRow(new Object[]{1L, "A (1)"});
        mc.addRow(new Object[]{2L, "B"});
        mc.addRow(new Object[]{2L, "B (1)"});
        mc.addRow(new Object[]{3L, "C"});
        mc.addRow(new Object[]{3L, "C (1)"});
        mc.addRow(new Object[]{3L, "C (2)"});
        mc.addRow(new Object[]{4L, "D"});
        BluetoothPbapVcardManager manager = createBluetoothPbapVcardManager(mc);
        ArrayList<String> nameList = manager.getContactNamesByNumber("111-111-111");

        // If there are multiple display name per id, first one is picked.
        assertEquals("A,1", nameList.get(0));
        assertEquals("B,2", nameList.get(1));
        assertEquals("C,3", nameList.get(2));
        assertEquals("D,4", nameList.get(3));
    }

    public void testGetDistinctContactIdSize() {
        MatrixCursor mc = new MatrixCursor(new String[]{ContactsContract.Data.CONTACT_ID});
        mc.addRow(new String[]{"1"});
        mc.addRow(new String[]{"1"});
        mc.addRow(new String[]{"2"});
        mc.addRow(new String[]{"2"});
        mc.addRow(new String[]{"3"});
        mc.addRow(new String[]{"3"});
        mc.addRow(new String[]{"3"});
        mc.addRow(new String[]{"4"});
        mc.addRow(new String[]{"5"});
        BluetoothPbapVcardManager manager = createBluetoothPbapVcardManager(mc);
        int size = manager.getContactsSize();

        assertEquals(5 + 1, size);  // +1 becoz of always has the 0.vcf
    }

    public void testGetPhonebookNameListOrderByIndex() {
        MatrixCursor mc = new MatrixCursor(
                new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        // test name duplication.
        mc.addRow(new Object[]{1L, "A"});
        mc.addRow(new Object[]{1L, "A (1)"});
        mc.addRow(new Object[]{2L, "B"});
        mc.addRow(new Object[]{2L, "B (1)"});
        mc.addRow(new Object[]{3L, "C"});
        mc.addRow(new Object[]{3L, "C (1)"});
        mc.addRow(new Object[]{3L, "C (2)"});
        mc.addRow(new Object[]{4L, "D"});
        // test default name.
        mc.addRow(new Object[]{5L, null});
        BluetoothPbapVcardManager manager = createBluetoothPbapVcardManager(mc);
        ArrayList<String> nameList = manager
                .getPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_INDEXED);

        // Skip the first one which is supposed to be owner name.
        assertEquals("A,1", nameList.get(1));
        assertEquals("B,2", nameList.get(2));
        assertEquals("C,3", nameList.get(3));
        assertEquals("D,4", nameList.get(4));
        assertEquals(getContext().getString(android.R.string.unknownName) + ",5", nameList.get(5));
    }

    public void testGetPhonebookNameListOrderByAlphabetical() {
        MatrixCursor mc = new MatrixCursor(
                new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        // test sorting order.
        mc.addRow(new Object[]{1L, "D"});
        mc.addRow(new Object[]{1L, "D (1)"});
        mc.addRow(new Object[]{2L, "C"});
        mc.addRow(new Object[]{2L, "C (1)"});
        mc.addRow(new Object[]{3L, "A"});
        mc.addRow(new Object[]{3L, "A (1)"});
        mc.addRow(new Object[]{3L, "A (2)"});
        mc.addRow(new Object[]{4L, "B"});
        BluetoothPbapVcardManager manager = createBluetoothPbapVcardManager(mc);
        ArrayList<String> nameList = manager
                .getPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL);

        // Skip the first one which is supposed to be owner name.
        assertEquals("A,3", nameList.get(1));
        assertEquals("B,4", nameList.get(2));
        assertEquals("C,2", nameList.get(3));
        assertEquals("D,1", nameList.get(4));
    }

    private BluetoothPbapVcardManager createBluetoothPbapVcardManager(Cursor result) {
        MockContentProvider contentProvider = new SimpleMockContentProvider(result);
        MockContentResolver contentResolver = new MockContentResolver();
        contentResolver.addProvider(ContactsContract.AUTHORITY, contentProvider);
        BluetoothMockContext mockContext = new BluetoothMockContext(contentResolver, getContext());
        return new BluetoothPbapVcardManager(mockContext);
    }
}
+161 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.tests.pbap;

import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.ContactsContract;
import android.test.AndroidTestCase;

import com.android.bluetooth.pbap.BluetoothPbapVcardManager;

public class ContactCursorFilterTest extends AndroidTestCase {

    public void testFilterByRangeWithoutDup() {
        MatrixCursor mc = new MatrixCursor(new String[]{
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{3L, "Test"});

        Cursor cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 1, 2);
        assertEquals(2, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        assertEquals(2L, getContactsIdFromCursor(cursor, 1));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 1, 3);
        assertEquals(3, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        assertEquals(2L, getContactsIdFromCursor(cursor, 1));
        assertEquals(3L, getContactsIdFromCursor(cursor, 2));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 2, 3);
        assertEquals(2, cursor.getCount());
        assertEquals(2L, getContactsIdFromCursor(cursor, 0));
        assertEquals(3L, getContactsIdFromCursor(cursor, 1));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 3, 3);
        assertEquals(1, cursor.getCount());
        assertEquals(3L, getContactsIdFromCursor(cursor, 0));
        cursor.close();
    }


    public void testFilterByRangeWithDup() {
        MatrixCursor mc = new MatrixCursor(new String[]{ContactsContract.CommonDataKinds.Phone
                .CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{3L, "Test"});

        Cursor cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 1, 2);
        assertEquals(2, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        assertEquals(2L, getContactsIdFromCursor(cursor, 1));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 1, 3);
        assertEquals(3, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        assertEquals(2L, getContactsIdFromCursor(cursor, 1));
        assertEquals(3L, getContactsIdFromCursor(cursor, 2));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 2, 3);
        assertEquals(2, cursor.getCount());
        assertEquals(2L, getContactsIdFromCursor(cursor, 0));
        assertEquals(3L, getContactsIdFromCursor(cursor, 1));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByRange(mc, 3, 3);
        assertEquals(1, cursor.getCount());
        assertEquals(3L, getContactsIdFromCursor(cursor, 0));
        cursor.close();
    }

    public void testFilterByOffsetWithoutDup() {
        MatrixCursor mc = new MatrixCursor(new String[]{ContactsContract.CommonDataKinds.Phone
                .CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{3L, "Test"});

        Cursor cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 1);
        assertEquals(1, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 2);
        assertEquals(1, cursor.getCount());
        assertEquals(2L, getContactsIdFromCursor(cursor, 0));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 3);
        assertEquals(1, cursor.getCount());
        assertEquals(3L, getContactsIdFromCursor(cursor, 0));
        cursor.close();
    }

    public void testFilterByOffsetWithDup() {
        MatrixCursor mc = new MatrixCursor(new String[]{ContactsContract.CommonDataKinds.Phone
                .CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{1L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{2L, "Test"});
        mc.addRow(new Object[]{3L, "Test"});

        Cursor cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 1);
        assertEquals(1, cursor.getCount());
        assertEquals(1L, getContactsIdFromCursor(cursor, 0));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 2);
        assertEquals(1, cursor.getCount());
        assertEquals(2L, getContactsIdFromCursor(cursor, 0));
        cursor.close();

        mc.moveToPosition(-1);
        cursor = BluetoothPbapVcardManager.ContactCursorFilter.filterByOffset(mc, 3);
        assertEquals(1, cursor.getCount());
        assertEquals(3L, getContactsIdFromCursor(cursor, 0));
        cursor.close();
        mc.moveToFirst();

    }

    private long getContactsIdFromCursor(Cursor cursor, int offset) {
        int index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
        cursor.moveToPosition(offset);
        return cursor.getLong(index);
    }
}