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

Commit 37393587 authored by Sal Savage's avatar Sal Savage Committed by Gerrit Code Review
Browse files

Merge changes I1d51bd0f,I82df4b47,I2d61f688 into main

* changes:
  Mock ContactsProvider for CallLogPullRequestTest
  Cleanup State Machines after connect tests
  Downgrade exceptions to warns for tests
parents 87926c63 c87909f2
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -726,7 +726,7 @@ public class PbapClientService extends ProfileService {

    void cleanupDevice(BluetoothDevice device) {
        if (Flags.pbapClientStorageRefactor()) {
            throw new UnsupportedOperationException("This is not needed with contacts storage");
            Log.w(TAG, "This should not be used in this configuration");
        }

        Log.d(TAG, "Cleanup device: " + device);
@@ -746,7 +746,7 @@ public class PbapClientService extends ProfileService {
     */
    public boolean isAccountTypeReady() {
        if (Flags.pbapClientStorageRefactor()) {
            throw new UnsupportedOperationException("This is not needed with contacts storage");
            Log.w(TAG, "This should not be used in this configuration");
        }
        return mPbapClientAccountManager.isAccountTypeInitialized();
    }
@@ -758,6 +758,9 @@ public class PbapClientService extends ProfileService {
     * @return True if the account addition was successful, False otherwise
     */
    public boolean addAccount(Account account) {
        if (Flags.pbapClientStorageRefactor()) {
            Log.w(TAG, "This should not be used in this configuration");
        }
        return mPbapClientAccountManager.addAccount(account);
    }

@@ -768,6 +771,9 @@ public class PbapClientService extends ProfileService {
     * @return True if the account removal was successful, False otherwise
     */
    public boolean removeAccount(Account account) {
        if (Flags.pbapClientStorageRefactor()) {
            Log.w(TAG, "This should not be used in this configuration");
        }
        return mPbapClientAccountManager.removeAccount(account);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -857,6 +857,7 @@ class PbapClientStateMachine extends StateMachine {
            case BluetoothProfile.STATE_CONNECTED:
                onConnectionStateChanged(BluetoothProfile.STATE_DISCONNECTING);
                // intentional fallthrough-- we want to broadcast both state changes
            case BluetoothProfile.STATE_CONNECTING:
            case BluetoothProfile.STATE_DISCONNECTING:
                onConnectionStateChanged(BluetoothProfile.STATE_DISCONNECTED);
                cleanup();
+4 −7
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.provider.ContactsContract;
import android.util.Log;
import android.util.Pair;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.VisibleForTesting;
import com.android.vcard.VCardEntry;
@@ -148,18 +147,16 @@ public class CallLogPullRequest extends PullRequest {
            Uri uri =
                    Uri.withAppendedPath(
                            ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(key));
            try (Cursor c =
                    BluetoothMethodProxy.getInstance()
                            .contentResolverQuery(
                                    mContext.getContentResolver(), uri, null, null, null)) {
            try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
                if (c != null && c.getCount() > 0) {
                    c.moveToNext();
                    String contactId =
                            c.getString(c.getColumnIndex(ContactsContract.PhoneLookup.CONTACT_ID));
                    Log.d(TAG, "onPullComplete: ID " + contactId + " key : " + key);
                    String where = ContactsContract.RawContacts.CONTACT_ID + "=" + contactId;
                    String where = ContactsContract.RawContacts.CONTACT_ID + "=?";
                    String[] args = new String[] {contactId};
                    mContext.getContentResolver()
                            .update(ContactsContract.RawContacts.CONTENT_URI, values, where, null);
                            .update(ContactsContract.RawContacts.CONTENT_URI, values, where, args);
                }
            }
        }
+37 −35
Original line number Diff line number Diff line
@@ -18,31 +18,28 @@ package com.android.bluetooth.pbapclient;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

import android.accounts.Account;
import android.content.Context;
import android.database.MatrixCursor;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.test.mock.MockContentResolver;
import android.util.SparseArray;

import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.vcard.VCardConstants;
import com.android.vcard.VCardEntry;
import com.android.vcard.VCardProperty;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@@ -54,30 +51,29 @@ import java.util.List;
@RunWith(AndroidJUnit4.class)
public class CallLogPullRequestTest {

    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

    private final Account mAccount = mock(Account.class);
    private final HashMap<String, Integer> mCallCounter = new HashMap<>();

    private Context mTargetContext;
    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

    @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance();
    @Mock private Context mMockContext;
    private MockContentResolver mMockContentResolver;
    private FakeContactsProvider mFakeContactsProvider;

    @Before
    public void setUp() {
        BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
        mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
    }

    @After
    public void tearDown() throws Exception {
        BluetoothMethodProxy.setInstanceForTesting(null);
        mMockContentResolver = new MockContentResolver();
        mFakeContactsProvider = new FakeContactsProvider();
        mMockContentResolver.addProvider(ContactsContract.AUTHORITY, mFakeContactsProvider);
        mMockContentResolver.addProvider(CallLog.AUTHORITY, mFakeContactsProvider);
        doReturn(mMockContentResolver).when(mMockContext).getContentResolver();
    }

    @Test
    public void testToString() {
        final String path = PbapPhonebook.ICH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);

        assertThat(request.toString()).isNotEmpty();
    }
@@ -86,7 +82,7 @@ public class CallLogPullRequestTest {
    public void onPullComplete_whenResultsAreNull() {
        final String path = PbapPhonebook.ICH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);
        request.setResults(null);

        request.onPullComplete();
@@ -99,7 +95,7 @@ public class CallLogPullRequestTest {
    public void onPullComplete_whenPathIsInvalid() {
        final String invalidPath = "invalidPath";
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, invalidPath, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, invalidPath, mCallCounter, mAccount);
        List<VCardEntry> results = new ArrayList<>();
        request.setResults(results);

@@ -113,7 +109,7 @@ public class CallLogPullRequestTest {
    public void onPullComplete_whenResultsAreEmpty() {
        final String path = PbapPhonebook.ICH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);
        List<VCardEntry> results = new ArrayList<>();
        request.setResults(results);

@@ -127,7 +123,7 @@ public class CallLogPullRequestTest {
    public void onPullComplete_whenThereIsNoPhoneProperty() {
        final String path = PbapPhonebook.MCH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);

        // Add some property which is NOT a phone number
        VCardProperty property = new VCardProperty();
@@ -151,7 +147,7 @@ public class CallLogPullRequestTest {
    public void onPullComplete_success() {
        final String path = PbapPhonebook.OCH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);
        List<VCardEntry> results = new ArrayList<>();

        final String phoneNum = "tel:0123456789";
@@ -180,20 +176,26 @@ public class CallLogPullRequestTest {
    public void updateTimesContacted_cursorIsClosed() {
        final String path = PbapPhonebook.OCH_PATH;
        final CallLogPullRequest request =
                new CallLogPullRequest(mTargetContext, path, mCallCounter, mAccount);
        mCallCounter.put("key", 1);

        MatrixCursor cursor =
                new MatrixCursor(new String[] {ContactsContract.PhoneLookup.CONTACT_ID});
        cursor.addRow(new Object[] {"contact_id"});
        doReturn(cursor)
                .when(mMapMethodProxy)
                .contentResolverQuery(any(), any(), eq(null), eq(null), eq(null));
        assertThat(cursor.isClosed()).isFalse();
                new CallLogPullRequest(mMockContext, path, mCallCounter, mAccount);

        String accountName = "AA:BB:CC:DD:EE:FF";
        mFakeContactsProvider.addAccount(Utils.ACCOUNT_TYPE, accountName);
        mFakeContactsProvider.addContact(
                Utils.ACCOUNT_TYPE,
                accountName,
                false,
                PbapPhonebook.LOCAL_PHONEBOOK_PATH,
                "555-123-4567");
        mCallCounter.put("555-123-4567", 1);

        request.updateTimesContacted();

        assertThat(cursor.isClosed()).isTrue();
        SparseArray<FakeContactsProvider.FakeRawContact> rawContacts =
                mFakeContactsProvider.getRawContacts();
        assertThat(rawContacts.size()).isEqualTo(1);
        FakeContactsProvider.FakeRawContact contact = rawContacts.valueAt(0);
        assertThat(contact).isNotNull();
        assertThat(contact.getTimesContacted()).isEqualTo(1);
    }

    private VCardProperty createProperty(String name, String value) {
+65 −10
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
@@ -72,14 +73,21 @@ public class FakeContactsProvider extends MockContentProvider {
        String mAccountName;
        boolean mStarred;
        String mPhonebook;
        int mTimesContacted;

        public FakeRawContact(
                int id, String accountType, String accountName, boolean starred, String phonebook) {
                int id,
                String accountType,
                String accountName,
                boolean starred,
                int timesContacted,
                String phonebook) {
            mId = id;
            mAccountType = accountType;
            mAccountName = accountName;
            mStarred = starred;
            mPhonebook = phonebook;
            mTimesContacted = timesContacted;
            mUri = RawContacts.CONTENT_URI.buildUpon().appendPath(String.valueOf(mId)).build();
        }

@@ -103,6 +111,10 @@ public class FakeContactsProvider extends MockContentProvider {
            return mStarred;
        }

        public int getTimesContacted() {
            return mTimesContacted;
        }

        public Uri getUri() {
            return mUri;
        }
@@ -110,6 +122,10 @@ public class FakeContactsProvider extends MockContentProvider {
        public void setPhonebook(String phonebook) {
            mPhonebook = phonebook;
        }

        public void setTimesContacted(int timesContacted) {
            mTimesContacted = timesContacted;
        }
    }

    public static class FakeData {
@@ -242,7 +258,7 @@ public class FakeContactsProvider extends MockContentProvider {
            String phone) {
        int rawContactId = getNextId();
        FakeRawContact contact =
                new FakeRawContact(rawContactId, accountType, accountName, favorite, phonebook);
                new FakeRawContact(rawContactId, accountType, accountName, favorite, 0, phonebook);
        mRawContacts.put(contact.getId(), contact);

        int id = getNextId();
@@ -305,6 +321,7 @@ public class FakeContactsProvider extends MockContentProvider {
                            accountType,
                            accountName,
                            (starred == null ? false : starred.booleanValue()),
                            0,
                            null);
            mRawContacts.put(id, contact);

@@ -340,17 +357,32 @@ public class FakeContactsProvider extends MockContentProvider {

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] selectionArgs) {
        // Update type 1: by where clause, raw contact ID, updates the SYNC1 field with a
        // phonebook type
        // Update type 1: by where clause, raw contact ID, either SYNC1 or times contacted
        if (where.contains(RawContacts._ID)) {
            int rawContactId = Integer.parseInt(selectionArgs[0]);
            FakeRawContact contact = mRawContacts.get(rawContactId);

            // Update the SYNC1 field with a phonebook type
            if (values.containsKey(RawContacts.SYNC1)) {
                String phonebook = values.getAsString(RawContacts.SYNC1);
                contact.setPhonebook(phonebook);
                mRawContacts.put(rawContactId, contact);
                return 1;
            }

            // Update the TIMES_CONTACTED field with the number of times contacted
            if (values.containsKey(RawContacts.TIMES_CONTACTED)) {
                Integer timesContacted = values.getAsInteger(RawContacts.TIMES_CONTACTED);
                if (timesContacted != null) {
                    contact.setTimesContacted(timesContacted.intValue());
                } else {
                    contact.setTimesContacted(0);
                }
                mRawContacts.put(rawContactId, contact);
                return 1;
            }
        }

        return 0;
    }

@@ -447,10 +479,33 @@ public class FakeContactsProvider extends MockContentProvider {
            String selection,
            String[] selectionArgs,
            String sortOrder) {
        Cursor cursor = mock(Cursor.class);
        // Ignore bad URIs
        if (uri == null) {
            return null;
        }

        // Use a UriMatcher if we begin to support many paths. For now though, this works just fine
        if (uri.toString().contains(ContactsContract.PhoneLookup.CONTENT_FILTER_URI.toString())) {
            MatrixCursor cursor =
                    new MatrixCursor(new String[] {ContactsContract.PhoneLookup.CONTACT_ID});

            String phoneNumber = uri.getLastPathSegment();
            if (phoneNumber != null) {
                for (int i = mData.size() - 1; i >= 0; i--) {
                    FakeData data = mData.valueAt(i);
                    if (data.getFields().containsKey(Phone.DATA)
                            && phoneNumber.equals(data.getField(Phone.DATA))) {
                        cursor.addRow(new Object[] {data.getRawContactId()});
                    }
                }
            }
            return cursor;
        }

        // Default: return a mock
        return mock(Cursor.class);
    }

    // *********************************************************************************************
    // * Utilities
    // *********************************************************************************************
Loading