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

Commit df194d67 authored by Sal Savage's avatar Sal Savage
Browse files

Create PbapPhonebookMetadata to hold size and version information

This change introduces a metadata class to hold phonebook metadata that
typically arrives as part of the response application parameter headers.
This info contains sizing and versioning data.

Bug: 365626536
Flag: EXEMPT, mechanical refactor, no logic change + tests
Test: atest com.android.bluetooth.pbapclient
Test: m com.android.btservices
Change-Id: I85b8e732784744f76f02b579e5d5d765207430f8
parent 27d5bbc2
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -355,10 +355,11 @@ class PbapClientConnectionHandler extends Handler {
                            /* list start offeset, start from beginning */ 0);

            // Download contacts in batches of size DEFAULT_BATCH_SIZE
            RequestPullPhoneBookSize requestPbSize = new RequestPullPhoneBookSize(path, params);
            RequestPullPhoneBookMetadata requestPbSize =
                    new RequestPullPhoneBookMetadata(path, params);
            requestPbSize.execute(mObexSession);

            int numberOfContactsRemaining = requestPbSize.getSize();
            int numberOfContactsRemaining = requestPbSize.getMetadata().getSize();
            int startOffset = 0;
            if (PbapPhonebook.LOCAL_PHONEBOOK_PATH.equals(path)) {
                // PBAP v1.2.3, Sec 3.1.5. The first contact in pb is owner card 0.vcf, which we
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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;

public class PbapPhonebookMetadata {
    private static final String TAG = PbapPhonebookMetadata.class.getSimpleName();

    public static final int INVALID_SIZE = -1;
    public static final String INVALID_DATABASE_IDENTIFIER = null;
    public static final String DEFAULT_DATABASE_IDENTIFIER = "0";
    public static final String INVALID_VERSION_COUNTER = null;

    private final String mPhonebook;
    private int mSize = INVALID_SIZE; // 2 byte number
    private String mDatabaseIdentifier = INVALID_DATABASE_IDENTIFIER; // 16 byte number as string
    private String mPrimaryVersionCounter = INVALID_VERSION_COUNTER; // 16 byte number as string
    private String mSecondaryVersionCounter = INVALID_VERSION_COUNTER; // 16 byte number as string

    PbapPhonebookMetadata(
            String phonebook,
            int size,
            String databaseIdentifier,
            String primaryVersionCounter,
            String secondaryVersionCounter) {
        mPhonebook = phonebook;
        mSize = size;
        mDatabaseIdentifier = databaseIdentifier;
        mPrimaryVersionCounter = primaryVersionCounter;
        mSecondaryVersionCounter = secondaryVersionCounter;
    }

    public String getPhonebook() {
        return mPhonebook;
    }

    public int getSize() {
        return mSize;
    }

    public String getDatabaseIdentifier() {
        return mDatabaseIdentifier;
    }

    public String getPrimaryVersionCounter() {
        return mPrimaryVersionCounter;
    }

    public String getSecondaryVersionCounter() {
        return mSecondaryVersionCounter;
    }

    @Override
    public String toString() {
        return "<"
                + TAG
                + (" phonebook=" + mPhonebook)
                + (" size=" + mSize)
                + (" databaseIdentifier=" + mDatabaseIdentifier)
                + (" primaryVersionCounter=" + mPrimaryVersionCounter)
                + (" secondaryVersionCounter=" + mSecondaryVersionCounter)
                + ">";
    }
}
+34 −7
Original line number Diff line number Diff line
@@ -19,14 +19,24 @@ package com.android.bluetooth.pbapclient;
import com.android.bluetooth.ObexAppParameters;
import com.android.obex.HeaderSet;

final class RequestPullPhoneBookSize extends PbapClientRequest {
    private static final String TAG = RequestPullPhoneBookSize.class.getSimpleName();
/**
 * This implements a PullPhonebook request, with the goal of only fetching metadata for the given
 * phonebook, but not the actual phonebook contents itself.
 *
 * <p>This is done by requesting the phonebook, but omitting the MaxListCount parameter, signaling
 * that we're not interested in the contents (PBAP 1.2.3, Section 5.1, C7 of the Response Format
 * table)
 */
final class RequestPullPhoneBookMetadata extends PbapClientRequest {
    private static final String TAG = RequestPullPhoneBookMetadata.class.getSimpleName();

    private static final String TYPE = "x-bt/phonebook";

    private int mSize = -1;
    private final String mPhonebook;
    private PbapPhonebookMetadata mResponse;

    RequestPullPhoneBookSize(String phonebook, PbapApplicationParameters params) {
    RequestPullPhoneBookMetadata(String phonebook, PbapApplicationParameters params) {
        mPhonebook = phonebook;
        mHeaderSet.setHeader(HeaderSet.NAME, phonebook);
        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);

@@ -47,13 +57,30 @@ final class RequestPullPhoneBookSize extends PbapClientRequest {

    @Override
    protected void readResponseHeaders(HeaderSet headerset) {
        int size = PbapPhonebookMetadata.INVALID_SIZE;
        String databaseIdentifier = PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER;
        String primaryVersionCounter = PbapPhonebookMetadata.INVALID_VERSION_COUNTER;
        String secondaryVersionCounter = PbapPhonebookMetadata.INVALID_VERSION_COUNTER;

        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
        if (oap.exists(PbapApplicationParameters.OAP_PHONEBOOK_SIZE)) {
            mSize = oap.getShort(PbapApplicationParameters.OAP_PHONEBOOK_SIZE);
            size = oap.getShort(PbapApplicationParameters.OAP_PHONEBOOK_SIZE);
        }

        mResponse =
                new PbapPhonebookMetadata(
                        mPhonebook,
                        size,
                        databaseIdentifier,
                        primaryVersionCounter,
                        secondaryVersionCounter);
    }

    public String getPhonebook() {
        return mPhonebook;
    }

    public int getSize() {
        return mSize;
    public PbapPhonebookMetadata getMetadata() {
        return mResponse;
    }
}
+239 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 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 static com.google.common.truth.Truth.assertThat;

import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class PbapPhonebookMetadataTest {
    private static final int SIZE = 5;
    private static final String DATABASE_IDENTIFIER = "dbid";
    private static final String PRIMARY_VERSION_COUNTER = "pvc";
    private static final String SECONDARY_VERSION_COUNTER = "svc";

    @Test
    public void testCreatePhonebookMetadata_forFavorites_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.FAVORITES_PATH,
                        SIZE,
                        DATABASE_IDENTIFIER,
                        PRIMARY_VERSION_COUNTER,
                        SECONDARY_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.FAVORITES_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier()).isEqualTo(DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter()).isEqualTo(PRIMARY_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter()).isEqualTo(SECONDARY_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forLocalPhonebook_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.LOCAL_PHONEBOOK_PATH,
                        SIZE,
                        DATABASE_IDENTIFIER,
                        PRIMARY_VERSION_COUNTER,
                        SECONDARY_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.LOCAL_PHONEBOOK_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier()).isEqualTo(DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter()).isEqualTo(PRIMARY_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter()).isEqualTo(SECONDARY_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forSimLocalPhonebook_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.SIM_PHONEBOOK_PATH,
                        SIZE,
                        DATABASE_IDENTIFIER,
                        PRIMARY_VERSION_COUNTER,
                        SECONDARY_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.SIM_PHONEBOOK_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier()).isEqualTo(DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter()).isEqualTo(PRIMARY_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter()).isEqualTo(SECONDARY_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forIncomingCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.ICH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.ICH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forOutgoingCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.OCH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.OCH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forMissedCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.MCH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.MCH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forSimIncomingCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.SIM_ICH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.SIM_ICH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forSimOutgoingCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.SIM_OCH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.SIM_OCH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }

    @Test
    public void testCreatePhonebookMetadata_forSimMissedCallHistory_metadataCreated() {
        PbapPhonebookMetadata metadata =
                new PbapPhonebookMetadata(
                        PbapPhonebook.SIM_MCH_PATH,
                        SIZE,
                        PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER,
                        PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        assertThat(metadata.getPhonebook()).isEqualTo(PbapPhonebook.SIM_MCH_PATH);
        assertThat(metadata.getSize()).isEqualTo(SIZE);
        assertThat(metadata.getDatabaseIdentifier())
                .isEqualTo(PbapPhonebookMetadata.INVALID_DATABASE_IDENTIFIER);
        assertThat(metadata.getPrimaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);
        assertThat(metadata.getSecondaryVersionCounter())
                .isEqualTo(PbapPhonebookMetadata.INVALID_VERSION_COUNTER);

        String str = metadata.toString();
        assertThat(str).isNotNull();
        assertThat(str.length()).isNotEqualTo(0);
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -30,9 +30,9 @@ import org.junit.runner.RunWith;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class RequestPullPhoneBookSizeTest {
public class RequestPullPhoneBookMetadataTest {

    RequestPullPhoneBookSize mRequest;
    RequestPullPhoneBookMetadata mRequest;

    @Before
    public void setUp() {
@@ -42,7 +42,8 @@ public class RequestPullPhoneBookSizeTest {
                        PbapPhonebook.FORMAT_VCARD_30,
                        PbapApplicationParameters.MAX_PHONEBOOK_SIZE,
                        /* startOffset= */ 0);
        mRequest = new RequestPullPhoneBookSize(/* pbName= */ "phonebook", /* params= */ params);
        mRequest =
                new RequestPullPhoneBookMetadata(/* pbName= */ "phonebook", /* params= */ params);
    }

    @Test
@@ -50,7 +51,7 @@ public class RequestPullPhoneBookSizeTest {
        try {
            HeaderSet headerSet = new HeaderSet();
            mRequest.readResponseHeaders(headerSet);
            assertThat(mRequest.getSize()).isEqualTo(-1);
            assertThat(mRequest.getMetadata().getSize()).isEqualTo(-1);
        } catch (Exception e) {
            assertWithMessage("Exception should not happen.").fail();
        }