1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.pbap; 18 19 import static org.mockito.Mockito.*; 20 21 import android.bluetooth.BluetoothAdapter; 22 import android.bluetooth.BluetoothDevice; 23 import android.bluetooth.BluetoothProfile; 24 import android.bluetooth.BluetoothSocket; 25 import android.content.Context; 26 import android.os.Handler; 27 import android.os.HandlerThread; 28 import android.support.test.InstrumentationRegistry; 29 import android.support.test.filters.MediumTest; 30 import android.support.test.runner.AndroidJUnit4; 31 32 import com.android.bluetooth.R; 33 import com.android.bluetooth.TestUtils; 34 import com.android.bluetooth.btservice.AdapterService; 35 36 import org.hamcrest.core.IsInstanceOf; 37 import org.junit.After; 38 import org.junit.Assert; 39 import org.junit.Assume; 40 import org.junit.Before; 41 import org.junit.Ignore; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.mockito.Mock; 45 import org.mockito.MockitoAnnotations; 46 47 @MediumTest 48 @RunWith(AndroidJUnit4.class) 49 public class PbapStateMachineTest { 50 private static final int TEST_NOTIFICATION_ID = 1000000; 51 52 private Context mTargetContext; 53 private BluetoothAdapter mAdapter; 54 private HandlerThread mHandlerThread; 55 private PbapStateMachine mPbapStateMachine; 56 private BluetoothDevice mTestDevice; 57 private Handler mHandler; 58 private BluetoothSocket mSocket; 59 private BluetoothPbapService mBluetoothPbapService; 60 61 @Mock private AdapterService mAdapterService; 62 63 @Before setUp()64 public void setUp() throws Exception { 65 mTargetContext = InstrumentationRegistry.getTargetContext(); 66 Assume.assumeTrue("Ignore test when BluetoothPbapService is not enabled", 67 mTargetContext.getResources().getBoolean(R.bool.profile_supported_pbap)); 68 MockitoAnnotations.initMocks(this); 69 TestUtils.setAdapterService(mAdapterService); 70 // This line must be called to make sure relevant objects are initialized properly 71 mAdapter = BluetoothAdapter.getDefaultAdapter(); 72 // Get a device for testing 73 mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); 74 75 mHandlerThread = new HandlerThread("PbapTestHandlerThread"); 76 mHandlerThread.start(); 77 mHandler = new Handler(mHandlerThread.getLooper()); 78 mBluetoothPbapService = mock(BluetoothPbapService.class); 79 doNothing().when(mBluetoothPbapService).checkOrGetPhonebookPermission(any()); 80 mPbapStateMachine = PbapStateMachine.make(mBluetoothPbapService, mHandlerThread.getLooper(), 81 mTestDevice, mSocket, mBluetoothPbapService, mHandler, TEST_NOTIFICATION_ID); 82 } 83 84 @After tearDown()85 public void tearDown() throws Exception { 86 if (!mTargetContext.getResources().getBoolean(R.bool.profile_supported_pbap)) { 87 return; 88 } 89 mHandlerThread.quitSafely(); 90 TestUtils.clearAdapterService(mAdapterService); 91 } 92 93 /** 94 * Test that initial state is WaitingForAuth 95 */ 96 @Test testInitialState()97 public void testInitialState() { 98 Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, 99 mPbapStateMachine.getConnectionState()); 100 Assert.assertThat(mPbapStateMachine.getCurrentState(), 101 IsInstanceOf.instanceOf(PbapStateMachine.WaitingForAuth.class)); 102 } 103 104 /** 105 * Test state transition from WaitingForAuth to Finished when the user rejected 106 */ 107 @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.") 108 @Test testStateTransition_WaitingForAuthToFinished()109 public void testStateTransition_WaitingForAuthToFinished() throws Exception { 110 mPbapStateMachine.sendMessage(PbapStateMachine.REJECTED); 111 Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, 112 mPbapStateMachine.getConnectionState()); 113 Assert.assertThat(mPbapStateMachine.getCurrentState(), 114 IsInstanceOf.instanceOf(PbapStateMachine.Finished.class)); 115 } 116 117 /** 118 * Test state transition from WaitingForAuth to Finished when the user rejected 119 */ 120 @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.") 121 @Test testStateTransition_WaitingForAuthToConnected()122 public void testStateTransition_WaitingForAuthToConnected() throws Exception { 123 mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED); 124 Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, 125 mPbapStateMachine.getConnectionState()); 126 Assert.assertThat(mPbapStateMachine.getCurrentState(), 127 IsInstanceOf.instanceOf(PbapStateMachine.Connected.class)); 128 } 129 130 /** 131 * Test state transition from Connected to Finished when the OBEX server is done 132 */ 133 @Ignore("Class BluetoothSocket is final and cannot be mocked. b/71512958: re-enable it.") 134 @Test testStateTransition_ConnectedToFinished()135 public void testStateTransition_ConnectedToFinished() throws Exception { 136 mPbapStateMachine.sendMessage(PbapStateMachine.AUTHORIZED); 137 Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, 138 mPbapStateMachine.getConnectionState()); 139 Assert.assertThat(mPbapStateMachine.getCurrentState(), 140 IsInstanceOf.instanceOf(PbapStateMachine.Connected.class)); 141 142 // PBAP OBEX transport is done. 143 mPbapStateMachine.sendMessage(PbapStateMachine.DISCONNECT); 144 Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, 145 mPbapStateMachine.getConnectionState()); 146 Assert.assertThat(mPbapStateMachine.getCurrentState(), 147 IsInstanceOf.instanceOf(PbapStateMachine.Finished.class)); 148 } 149 } 150