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

Commit 2f275625 authored by Kihong Seong's avatar Kihong Seong Committed by Automerger Merge Worker
Browse files

Merge "Add tests for BluetoothMapMasInstance and BluetoothMapObexServer" into...

Merge "Add tests for BluetoothMapMasInstance and BluetoothMapObexServer" into tm-qpr-dev am: 06092fa3

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/20876983



Change-Id: I5f16e9c8851bbe5f545243d75766e57bc9456ac6
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents a3dd979b 06092fa3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package com.android.bluetooth;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.PeriodicAdvertisingCallback;
import android.bluetooth.le.PeriodicAdvertisingManager;
import android.bluetooth.le.ScanResult;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -161,6 +163,14 @@ public class BluetoothMethodProxy {
        return contentResolver.openInputStream(uri);
    }

    /**
     * Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}.
     */
    public ContentProviderClient contentResolverAcquireUnstableContentProviderClient(
            ContentResolver contentResolver, @NonNull String name) {
        return contentResolver.acquireUnstableContentProviderClient(name);
    }

    /**
     * Proxies {@link Context#sendBroadcast(Intent)}.
     */
+7 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.bluetooth.ObexServerSockets;
import com.android.bluetooth.map.BluetoothMapContentObserver.Msg;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
import com.android.bluetooth.sdp.SdpManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.obex.ServerSession;

import java.io.IOException;
@@ -39,8 +40,10 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

public class BluetoothMapMasInstance implements IObexConnectionHandler {
    private final String mTag;
    private static volatile int sInstanceCounter = 0;
    @VisibleForTesting
    final String mTag;
    @VisibleForTesting
    static volatile int sInstanceCounter = 0;

    private static final boolean D = BluetoothMapService.DEBUG;
    private static final boolean V = BluetoothMapService.VERBOSE;
@@ -146,7 +149,8 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler {
    }

    /* Needed only for test */
    protected BluetoothMapMasInstance() {
    @VisibleForTesting
    BluetoothMapMasInstance() {
        mTag = "BluetoothMapMasInstance" + sInstanceCounter++;
    }

+10 −6
Original line number Diff line number Diff line
@@ -29,9 +29,11 @@ import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.util.Log;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.SignedLongLong;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
import com.android.bluetooth.mapapi.BluetoothMapContract;
import com.android.internal.annotations.VisibleForTesting;
import com.android.obex.HeaderSet;
import com.android.obex.Operation;
import com.android.obex.ResponseCodes;
@@ -168,8 +170,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
     *
     */
    private ContentProviderClient acquireUnstableContentProviderOrThrow() throws RemoteException {
        ContentProviderClient providerClient =
                mResolver.acquireUnstableContentProviderClient(mAuthority);
        ContentProviderClient providerClient = BluetoothMethodProxy.getInstance()
                .contentResolverAcquireUnstableContentProviderClient(mResolver, mAuthority);
        if (providerClient == null) {
            throw new RemoteException("Failed to acquire provider for " + mAuthority);
        }
@@ -276,7 +278,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
     *        folder.getFolderId() will be used to query sub-folders.
     *        Use a parentFolder with id -1 to get all folders from root.
     */
    private void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException {
    @VisibleForTesting
    void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException {
        // Select all parent folders
        BluetoothMapFolderElement newFolder;

@@ -529,7 +532,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
                            + appParams.getChatState() + ", ChatStatusConvoId: "
                            + appParams.getChatStateConvoIdString());
                }
                return setOwnerStatus(name, appParams);
                return setOwnerStatus(appParams);
            }

        } catch (RemoteException e) {
@@ -841,7 +844,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
        return ResponseCodes.OBEX_HTTP_OK;
    }

    private int setOwnerStatus(String msgHandle, BluetoothMapAppParams appParams)
    @VisibleForTesting
    int setOwnerStatus(BluetoothMapAppParams appParams)
            throws RemoteException {
        // This does only work for IM
        if (mAccount != null && mAccount.getType() == BluetoothMapUtils.TYPE.IM) {
@@ -1845,7 +1849,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
                            + appParams.getChatState() + ", ChatStatusConvoId: "
                            + appParams.getChatStateConvoIdString());
                }
                return setOwnerStatus(name, appParams);
                return setOwnerStatus(appParams);
            }

        } catch (RemoteException e) {
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 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.map;

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

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothMapMasInstanceTest {
    private static final int TEST_MAS_ID = 1;
    private static final boolean TEST_ENABLE_SMS_MMS = true;
    private static final String TEST_NAME = "test_name";
    private static final String TEST_PACKAGE_NAME = "test.package.name";
    private static final String TEST_ID = "1111";
    private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider";
    private static final Drawable TEST_DRAWABLE = new ColorDrawable();
    private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.EMAIL;
    private static final String TEST_UCI = "uci";
    private static final String TEST_UCI_PREFIX = "uci_prefix";

    private BluetoothMapAccountItem mAccountItem;

    @Mock
    private Context mContext;
    @Mock
    private BluetoothMapService mMapService;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME,
                TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX);
    }

    @Test
    public void constructor_withNoParameters() {
        BluetoothMapMasInstance instance = new BluetoothMapMasInstance();

        assertThat(instance.mTag).isEqualTo(
                "BluetoothMapMasInstance" + (BluetoothMapMasInstance.sInstanceCounter - 1));
    }

    @Test
    public void toString_returnsInfo() {
        BluetoothMapMasInstance instance = new BluetoothMapMasInstance(mMapService, mContext,
                mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS);

        String expected = "MasId: " + TEST_MAS_ID + " Uri:" + mAccountItem.mBase_uri + " SMS/MMS:"
                + TEST_ENABLE_SMS_MMS;
        assertThat(instance.toString()).isEqualTo(expected);
    }
}
+195 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 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.map;

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.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.ContentProviderClient;
import android.content.Context;
import android.database.MatrixCursor;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.RemoteException;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.bluetooth.BluetoothMethodProxy;
import com.android.bluetooth.mapapi.BluetoothMapContract;
import com.android.obex.ResponseCodes;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class BluetoothMapObexServerTest {
    private static final int TEST_MAS_ID = 1;
    private static final boolean TEST_ENABLE_SMS_MMS = true;
    private static final String TEST_NAME = "test_name";
    private static final String TEST_PACKAGE_NAME = "test.package.name";
    private static final String TEST_ID = "1111";
    private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider";
    private static final Drawable TEST_DRAWABLE = new ColorDrawable();
    private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.IM;
    private static final String TEST_UCI = "uci";
    private static final String TEST_UCI_PREFIX = "uci_prefix";

    private BluetoothMapAccountItem mAccountItem;
    private BluetoothMapMasInstance mMasInstance;
    private BluetoothMapObexServer mObexServer;
    private BluetoothMapAppParams mParams;

    @Mock
    private Context mContext;
    @Mock
    private BluetoothMapService mMapService;
    @Mock
    private ContentProviderClient mProviderClient;
    @Mock
    private BluetoothMapContentObserver mObserver;
    @Spy
    private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance();

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
        doReturn(mProviderClient).when(
                mMapMethodProxy).contentResolverAcquireUnstableContentProviderClient(any(), any());
        mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME,
                TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX);
        mMasInstance = new BluetoothMapMasInstance(mMapService, mContext,
                mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS);
        mParams = new BluetoothMapAppParams();
        mObexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance,
                mAccountItem, TEST_ENABLE_SMS_MMS);
    }

    @Test
    public void setOwnerStatus_withAccountTypeEmail() throws Exception {
        doReturn(null).when(mProviderClient).query(any(), any(), any(), any(), any());
        BluetoothMapAccountItem accountItemWithTypeEmail = BluetoothMapAccountItem.create(TEST_ID,
                TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE,
                BluetoothMapUtils.TYPE.EMAIL, TEST_UCI, TEST_UCI_PREFIX);
        BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver,
                mMasInstance, accountItemWithTypeEmail, TEST_ENABLE_SMS_MMS);

        assertThat(obexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_UNAVAILABLE);
    }

    @Test
    public void setOwnerStatus_withAppParamsInvalid() throws Exception {
        BluetoothMapAppParams params = mock(BluetoothMapAppParams.class);
        when(params.getPresenceAvailability()).thenReturn(
                BluetoothMapAppParams.INVALID_VALUE_PARAMETER);
        when(params.getPresenceStatus()).thenReturn(null);
        when(params.getLastActivity()).thenReturn(
                (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER);
        when(params.getChatState()).thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER);
        when(params.getChatStateConvoIdString()).thenReturn(null);

        assertThat(mObexServer.setOwnerStatus(params)).isEqualTo(
                ResponseCodes.OBEX_HTTP_PRECON_FAILED);
    }

    @Test
    public void setOwnerStatus_withNonNullBundle() throws Exception {
        setUpBluetoothMapAppParams(mParams);
        Bundle bundle = new Bundle();
        when(mProviderClient.call(any(), any(), any())).thenReturn(bundle);

        assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_OK);
    }

    @Test
    public void setOwnerStatus_withNullBundle() throws Exception {
        setUpBluetoothMapAppParams(mParams);
        when(mProviderClient.call(any(), any(), any())).thenReturn(null);

        assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED);
    }

    @Test
    public void setOwnerStatus_withRemoteExceptionThrown() throws Exception {
        setUpBluetoothMapAppParams(mParams);
        doThrow(RemoteException.class).when(mProviderClient).call(any(), any(), any());

        assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_UNAVAILABLE);
    }

    @Test
    public void setOwnerStatus_withNullPointerExceptionThrown() throws Exception {
        setUpBluetoothMapAppParams(mParams);
        doThrow(NullPointerException.class).when(mProviderClient).call(any(), any(), any());

        assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_UNAVAILABLE);
    }

    @Test
    public void setOwnerStatus_withIllegalArgumentExceptionThrown() throws Exception {
        setUpBluetoothMapAppParams(mParams);
        doThrow(IllegalArgumentException.class).when(mProviderClient).call(any(), any(), any());

        assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo(
                ResponseCodes.OBEX_HTTP_UNAVAILABLE);
    }

    @Test
    public void addEmailFolders() throws Exception {
        MatrixCursor cursor = new MatrixCursor(new String[]{BluetoothMapContract.FolderColumns.NAME,
                BluetoothMapContract.FolderColumns._ID});
        long parentId = 1;
        long childId = 2;
        cursor.addRow(new Object[]{"test_name", childId});
        cursor.moveToFirst();
        BluetoothMapFolderElement parentFolder = new BluetoothMapFolderElement("parent", null);
        parentFolder.setFolderId(parentId);
        doReturn(cursor).when(mProviderClient).query(any(), any(),
                eq(BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " + parentId), any(),
                any());

        mObexServer.addEmailFolders(parentFolder);

        assertThat(parentFolder.getFolderById(childId)).isNotNull();
    }

    private void setUpBluetoothMapAppParams(BluetoothMapAppParams params) {
        params.setPresenceAvailability(1);
        params.setPresenceStatus("test_presence_status");
        params.setLastActivity(0);
        params.setChatState(1);
        params.setChatStateConvoId(1, 1);
    }
}