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

Commit 7cc6a4da authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Add tests for SapServer

It adds simple tests.
Tests sending messages should be added in following CLs.

Tag: #stability
Bug: 237708568
Test: atest BluetoothInstrumentationTests

Change-Id: I3d95be363d0b8b237dc2247c1326d9824ea3ef3c
parent 1790bbc9
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.bluetooth.R;
import com.android.internal.annotations.VisibleForTesting;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -99,7 +100,8 @@ public class SapServer extends Thread implements Callback {
    /* We store the mMaxMessageSize, as we need a copy of it when the init. sequence completes */
    private int mMaxMsgSize = 0;
    /* keep track of the current RIL test mode */
    private int mTestMode = SapMessage.INVALID_VALUE; // used to set the RIL in test mode
    @VisibleForTesting
    int mTestMode = SapMessage.INVALID_VALUE; // used to set the RIL in test mode

    /**
     * SapServer constructor
+143 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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.sap;

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

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Handler;

import androidx.test.InstrumentationRegistry;

import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;

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

import java.io.InputStream;
import java.io.OutputStream;

@RunWith(JUnit4.class)
public class SapServerTest {
    @Rule
    public final MockitoRule mockito = MockitoJUnit.rule();

    private final static long TIMEOUT_MS = 5_000;

    private Context mContext;
    private BluetoothAdapter mAdapter;
    private BluetoothDevice mTestDevice;
    @Mock private AdapterService mAdapterService;
    @Mock private SapService mSapService;
    @Mock private Handler mHandler;
    @Mock private InputStream mRfcommInStream;
    @Mock private OutputStream mRfcommOutStream;
    @Mock private NotificationManager mNotificationManager;
    private SapServer mSapServer;

    @Before
    public void setUp() throws Exception {
        Context targetContext = InstrumentationRegistry.getTargetContext();
        TestUtils.setAdapterService(mAdapterService);

        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mContext = spy(new ContextWrapper(targetContext));

        doReturn(Context.NOTIFICATION_SERVICE).when(mContext)
                .getSystemServiceName(NotificationManager.class);
        doReturn(mNotificationManager).when(mContext)
                .getSystemService(Context.NOTIFICATION_SERVICE);

        mSapServer = new SapServer(mHandler, mContext, mRfcommInStream, mRfcommOutStream);
    }

    @After
    public void tearDown() throws Exception {
        TestUtils.clearAdapterService(mAdapterService);
    }

    @Test
    public void testSetTestMode() {
        int previousValue = mSapServer.mTestMode;

        if (SapMessage.TEST) {
            mSapServer.setTestMode(SapMessage.TEST_MODE_ENABLE);
            assertThat(mSapServer.mTestMode).isEqualTo(SapMessage.TEST_MODE_ENABLE);
            mSapServer.setTestMode(SapMessage.TEST_MODE_DISABLE);
            assertThat(mSapServer.mTestMode).isEqualTo(SapMessage.TEST_MODE_DISABLE);

            // recover the previous value
            mSapServer.setTestMode(previousValue);
        } else {
            mSapServer.setTestMode(SapMessage.TEST_MODE_ENABLE);
            assertThat(mSapServer.mTestMode).isEqualTo(previousValue);
        }
    }

    @Test
    public void testClearNotification() {
        mSapServer.clearNotification();

        verify(mNotificationManager).cancel(SapServer.NOTIFICATION_ID);
    }

    @Test
    public void testSetNotification() {
        int type = SapMessage.DISC_GRACEFULL;
        int flag = 0;

        mSapServer.setNotification(type, flag);

        verify(mNotificationManager).createNotificationChannel(any(NotificationChannel.class));
        verify(mNotificationManager).notify(eq(SapServer.NOTIFICATION_ID), any(Notification.class));
    }

    @Test
    public void testEmptyInputStream() throws Exception {
        // Simulate as if EOS was reached.
        when(mRfcommInStream.read()).thenReturn(-1);
        mSapServer.start();

        // Wait for the server finished
        mSapServer.join(TIMEOUT_MS);

        // Check if streams are closed.
        verify(mRfcommInStream).close();
        verify(mRfcommOutStream).close();
    }
}
+83 −7
Original line number Diff line number Diff line
@@ -13,12 +13,18 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.bluetooth.sap;

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

import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import androidx.test.InstrumentationRegistry;
@@ -26,12 +32,11 @@ import androidx.test.filters.MediumTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.bluetooth.R;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.storage.DatabaseManager;

import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
@@ -40,9 +45,15 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@MediumTest
@RunWith(AndroidJUnit4.class)
public class SapServiceTest {
    private static final int TIMEOUT_MS = 5_000;

    private SapService mService = null;
    private BluetoothAdapter mAdapter = null;
    private Context mTargetContext;
@@ -50,6 +61,8 @@ public class SapServiceTest {
    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

    @Mock private AdapterService mAdapterService;
    @Mock private DatabaseManager mDatabaseManager;
    private BluetoothDevice mDevice;

    @Before
    public void setUp() throws Exception {
@@ -61,10 +74,11 @@ public class SapServiceTest {
        doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
        TestUtils.startService(mServiceRule, SapService.class);
        mService = SapService.getSapService();
        Assert.assertNotNull(mService);
        assertThat(mService).isNotNull();
        // Try getting the Bluetooth adapter
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        Assert.assertNotNull(mAdapter);
        assertThat(mAdapter).isNotNull();
        mDevice = TestUtils.getTestDevice(mAdapter, 0);
    }

    @After
@@ -74,12 +88,74 @@ public class SapServiceTest {
        }
        TestUtils.stopService(mServiceRule, SapService.class);
        mService = SapService.getSapService();
        Assert.assertNull(mService);
        assertThat(mService).isNull();
        TestUtils.clearAdapterService(mAdapterService);
    }

    @Test
    public void testInitialize() {
        Assert.assertNotNull(SapService.getSapService());
    public void testGetSapService() {
        assertThat(mService).isEqualTo(SapService.getSapService());
        assertThat(mService.getConnectedDevices()).isEmpty();
    }

    /**
     * Test stop SAP Service
     */
    @Test
    public void testStopSapService() throws Exception {
        AtomicBoolean stopResult = new AtomicBoolean();
        AtomicBoolean startResult = new AtomicBoolean();
        CountDownLatch latch = new CountDownLatch(1);

        // SAP Service is already running: test stop(). Note: must be done on the main thread
        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
            public void run() {
                stopResult.set(mService.stop());
                startResult.set(mService.start());
                latch.countDown();
            }
        });

        assertThat(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
        assertThat(stopResult.get()).isTrue();
        assertThat(startResult.get()).isTrue();
    }

    /**
     * Test get connection policy for BluetoothDevice
     */
    @Test
    public void testGetConnectionPolicy() {
        when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
        when(mDatabaseManager
                .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
                .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
        assertThat(mService.getConnectionPolicy(mDevice))
                .isEqualTo(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);

        when(mDatabaseManager
                .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
                .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
        assertThat(mService.getConnectionPolicy(mDevice))
                .isEqualTo(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);

        when(mDatabaseManager
                .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP))
                .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);

        assertThat(mService.getConnectionPolicy(mDevice))
                .isEqualTo(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
    }

    @Test
    public void testGetRemoteDevice() {
        assertThat(mService.getRemoteDevice()).isNull();
    }

    @Test
    public void testGetRemoteDeviceName() {
        assertThat(SapService.getRemoteDeviceName()).isNull();
    }
}