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

Commit 69cc2303 authored by Tony Mak's avatar Tony Mak Committed by Android Git Automerger
Browse files

am 5c6add3b: Merge "Add unit test for commit "Support work contacts in HFP,...

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

* commit '5c6add3b':
  Add unit test for commit "Support work contacts in HFP, PBAP, MAP"
parents bc85e9db 5c6add3b
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);
    }
}