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

Commit 3732878c authored by Kihong Seong's avatar Kihong Seong
Browse files

Add tests for BluetoothMapMasInstance and BluetoothMapObexServer

Bug: 237467631
Test: atest BluetoothInstrumentationTests
Change-Id: I11a049cc3ac35f05f58917dd5c592100f75d4300
Merged-In: I11a049cc3ac35f05f58917dd5c592100f75d4300
(cherry picked from commit d026c09f)
parent 07bf5635
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);
    }
}