1 /* 2 * Copyright (C) 2018 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 package com.android.server.deviceidle; 17 18 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; 23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; 24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 26 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertTrue; 29 import static org.mockito.ArgumentMatchers.any; 30 import static org.mockito.ArgumentMatchers.anyBoolean; 31 import static org.mockito.ArgumentMatchers.eq; 32 33 import android.bluetooth.BluetoothDevice; 34 import android.bluetooth.BluetoothManager; 35 import android.bluetooth.BluetoothProfile; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.os.Handler; 39 40 import androidx.test.runner.AndroidJUnit4; 41 42 import com.android.server.DeviceIdleInternal; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.Answers; 49 import org.mockito.InOrder; 50 import org.mockito.Mock; 51 import org.mockito.MockitoSession; 52 import org.mockito.quality.Strictness; 53 54 import java.util.Arrays; 55 56 /** 57 * Tests for {@link com.android.server.deviceidle.BluetoothConstraint}. 58 */ 59 @RunWith(AndroidJUnit4.class) 60 public class BluetoothConstraintTest { 61 62 private MockitoSession mMockingSession; 63 64 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 65 private Context mContext; 66 67 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 68 private Handler mHandler; 69 70 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 71 private BluetoothManager mBluetoothManager; 72 73 @Mock 74 private DeviceIdleInternal mDeviceIdleService; 75 76 private BluetoothConstraint mConstraint; 77 78 @Before setUp()79 public void setUp() { 80 mMockingSession = mockitoSession() 81 .initMocks(this) 82 .strictness(Strictness.LENIENT) 83 .startMocking(); 84 doReturn(mBluetoothManager) 85 .when(mContext).getSystemService(BluetoothManager.class); 86 mConstraint = new BluetoothConstraint(mContext, mHandler, mDeviceIdleService); 87 } 88 89 @After tearDown()90 public void tearDown() { 91 if (mMockingSession != null) { 92 mMockingSession.finishMocking(); 93 } 94 } 95 96 @Test testIsConnected_noBluetoothAdapter()97 public void testIsConnected_noBluetoothAdapter() { 98 doReturn(null).when(mBluetoothManager).getAdapter(); 99 assertFalse(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); 100 } 101 102 @Test testIsConnected_noConnectedDevice()103 public void testIsConnected_noConnectedDevice() { 104 enableBluetooth(true); 105 assertFalse(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); 106 } 107 108 @Test testIsConnected_twoConnectedDevices()109 public void testIsConnected_twoConnectedDevices() { 110 enableBluetooth(true, mock(BluetoothDevice.class), mock(BluetoothDevice.class)); 111 assertTrue(BluetoothConstraint.isBluetoothConnected(mBluetoothManager)); 112 } 113 114 @Test testStartMonitoring_updatesActiveAtCorrectTimes()115 public void testStartMonitoring_updatesActiveAtCorrectTimes() { 116 // First setup -> no callbacks should fire. 117 BluetoothConstraint constraint = mConstraint; 118 verify(mDeviceIdleService, never()).onConstraintStateChanged(any(), anyBoolean()); 119 verify(mContext, never()).registerReceiver(eq(constraint.mReceiver), any()); 120 121 InOrder order = inOrder(mDeviceIdleService); 122 123 // No devices -> active=false should be triggered. 124 enableBluetooth(true); 125 constraint.startMonitoring(); 126 order.verify(mDeviceIdleService, times(1)).onConstraintStateChanged(any(), eq(false)); 127 128 // One device -> active=true should be triggered. 129 enableBluetooth(true, mock(BluetoothDevice.class)); 130 constraint.mReceiver.onReceive( 131 mContext, new Intent(BluetoothDevice.ACTION_ACL_CONNECTED)); 132 constraint.startMonitoring(); 133 order.verify(mDeviceIdleService, times(1)).exitIdle(eq("bluetooth")); 134 135 // Stop monitoring -> broadcast receiver should be unregistered. 136 constraint.stopMonitoring(); 137 verify(mContext, times(1)).unregisterReceiver(eq(constraint.mReceiver)); 138 order.verifyNoMoreInteractions(); 139 140 } 141 enableBluetooth(boolean enabled, BluetoothDevice... devices)142 private void enableBluetooth(boolean enabled, BluetoothDevice... devices) { 143 when(mBluetoothManager.getAdapter().isEnabled()).thenReturn(enabled); 144 when(mBluetoothManager.getConnectedDevices(eq(BluetoothProfile.GATT))) 145 .thenReturn(Arrays.asList(devices)); 146 } 147 } 148