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.btservice;
18 
19 import static android.bluetooth.BluetoothAdapter.STATE_BLE_ON;
20 import static android.bluetooth.BluetoothAdapter.STATE_BLE_TURNING_OFF;
21 import static android.bluetooth.BluetoothAdapter.STATE_BLE_TURNING_ON;
22 import static android.bluetooth.BluetoothAdapter.STATE_OFF;
23 import static android.bluetooth.BluetoothAdapter.STATE_ON;
24 import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
25 import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 import static com.google.common.truth.Truth.assertWithMessage;
29 
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.*;
32 
33 import android.app.AlarmManager;
34 import android.app.AppOpsManager;
35 import android.app.admin.DevicePolicyManager;
36 import android.bluetooth.BluetoothAdapter;
37 import android.bluetooth.BluetoothDevice;
38 import android.bluetooth.BluetoothManager;
39 import android.bluetooth.BluetoothProfile;
40 import android.bluetooth.IBluetoothCallback;
41 import android.companion.CompanionDeviceManager;
42 import android.content.Context;
43 import android.content.pm.ApplicationInfo;
44 import android.content.pm.PackageManager;
45 import android.content.pm.PermissionInfo;
46 import android.content.res.Resources;
47 import android.hardware.display.DisplayManager;
48 import android.media.AudioManager;
49 import android.os.BatteryStatsManager;
50 import android.os.Binder;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.Looper;
54 import android.os.Message;
55 import android.os.PowerManager;
56 import android.os.Process;
57 import android.os.RemoteException;
58 import android.os.UserHandle;
59 import android.os.UserManager;
60 import android.os.test.TestLooper;
61 import android.permission.PermissionCheckerManager;
62 import android.permission.PermissionManager;
63 import android.platform.test.annotations.DisableFlags;
64 import android.platform.test.annotations.EnableFlags;
65 import android.platform.test.flag.junit.FlagsParameterization;
66 import android.platform.test.flag.junit.SetFlagsRule;
67 import android.provider.Settings;
68 import android.sysprop.BluetoothProperties;
69 import android.test.mock.MockContentProvider;
70 import android.test.mock.MockContentResolver;
71 import android.util.Log;
72 
73 import androidx.test.InstrumentationRegistry;
74 import androidx.test.filters.MediumTest;
75 
76 import com.android.bluetooth.TestUtils;
77 import com.android.bluetooth.Utils;
78 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreNativeInterface;
79 import com.android.bluetooth.flags.Flags;
80 import com.android.bluetooth.gatt.AdvertiseManagerNativeInterface;
81 import com.android.bluetooth.gatt.DistanceMeasurementNativeInterface;
82 import com.android.bluetooth.gatt.GattNativeInterface;
83 import com.android.bluetooth.le_scan.PeriodicScanNativeInterface;
84 import com.android.bluetooth.le_scan.ScanNativeInterface;
85 import com.android.bluetooth.sdp.SdpManagerNativeInterface;
86 import com.android.internal.app.IBatteryStats;
87 
88 import libcore.util.HexEncoding;
89 
90 import org.junit.After;
91 import org.junit.Before;
92 import org.junit.Rule;
93 import org.junit.Test;
94 import org.junit.runner.RunWith;
95 import org.mockito.Mock;
96 import org.mockito.junit.MockitoJUnit;
97 import org.mockito.junit.MockitoRule;
98 
99 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
100 import platform.test.runner.parameterized.Parameters;
101 
102 import java.io.FileDescriptor;
103 import java.io.PrintWriter;
104 import java.security.InvalidKeyException;
105 import java.security.NoSuchAlgorithmException;
106 import java.util.List;
107 import java.util.Map;
108 
109 import javax.crypto.Mac;
110 import javax.crypto.spec.SecretKeySpec;
111 
112 @MediumTest
113 @RunWith(ParameterizedAndroidJunit4.class)
114 public class AdapterServiceTest {
115     private static final String TAG = AdapterServiceTest.class.getSimpleName();
116     private static final String TEST_BT_ADDR_1 = "00:11:22:33:44:55";
117     private static final String TEST_BT_ADDR_2 = "00:11:22:33:44:66";
118 
119     private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1;
120     private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
121     private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
122 
123     private MockAdapterService mAdapterService;
124 
125     static class MockAdapterService extends AdapterService {
126 
127         int mSetProfileServiceStateCounter = 0;
128 
MockAdapterService(Looper looper)129         MockAdapterService(Looper looper) {
130             super(looper);
131         }
132 
133         @Override
setProfileServiceState(int profileId, int state)134         void setProfileServiceState(int profileId, int state) {
135             mSetProfileServiceStateCounter++;
136         }
137     }
138 
139     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
140 
141     private @Mock Context mMockContext;
142     private @Mock ApplicationInfo mMockApplicationInfo;
143     private @Mock Resources mMockResources;
144     private @Mock ProfileService mMockGattService;
145     private @Mock ProfileService mMockService;
146     private @Mock ProfileService mMockService2;
147     private @Mock IBluetoothCallback mIBluetoothCallback;
148     private @Mock Binder mBinder;
149     private @Mock android.app.Application mApplication;
150     private @Mock MetricsLogger mMockMetricsLogger;
151     private @Mock AdapterNativeInterface mNativeInterface;
152     private @Mock BluetoothKeystoreNativeInterface mKeystoreNativeInterface;
153     private @Mock BluetoothQualityReportNativeInterface mQualityNativeInterface;
154     private @Mock SdpManagerNativeInterface mSdpNativeInterface;
155     private @Mock AdvertiseManagerNativeInterface mAdvertiseNativeInterface;
156     private @Mock DistanceMeasurementNativeInterface mDistanceNativeInterface;
157     private @Mock GattNativeInterface mGattNativeInterface;
158     private @Mock PeriodicScanNativeInterface mPeriodicNativeInterface;
159     private @Mock ScanNativeInterface mScanNativeInterface;
160     private @Mock JniCallbacks mJniCallbacks;
161 
162     @Rule public final SetFlagsRule mSetFlagsRule;
163 
164     // SystemService that are not mocked
165     private BluetoothManager mBluetoothManager;
166     private CompanionDeviceManager mCompanionDeviceManager;
167     private DisplayManager mDisplayManager;
168     private PowerManager mPowerManager;
169     private PermissionCheckerManager mPermissionCheckerManager;
170     private PermissionManager mPermissionManager;
171     // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the
172     // underlying binder calls.
173     final BatteryStatsManager mBatteryStatsManager =
174             new BatteryStatsManager(mock(IBatteryStats.class));
175 
176     private static final int CONTEXT_SWITCH_MS = 100;
177 
178     private PackageManager mMockPackageManager;
179     private MockContentResolver mMockContentResolver;
180     private int mForegroundUserId;
181     private TestLooper mLooper;
182 
configureEnabledProfiles()183     static void configureEnabledProfiles() {
184         Log.e(TAG, "configureEnabledProfiles");
185 
186         for (int profileId = 0; profileId <= BluetoothProfile.MAX_PROFILE_ID; profileId++) {
187             boolean enabled =
188                     profileId == BluetoothProfile.PAN
189                             || profileId == BluetoothProfile.PBAP
190                             || profileId == BluetoothProfile.GATT;
191 
192             Config.setProfileEnabled(profileId, enabled);
193         }
194     }
195 
mockGetSystemService(String serviceName, Class<T> serviceClass, T mockService)196     <T> void mockGetSystemService(String serviceName, Class<T> serviceClass, T mockService) {
197         TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass, mockService);
198     }
199 
mockGetSystemService(String serviceName, Class<T> serviceClass)200     <T> T mockGetSystemService(String serviceName, Class<T> serviceClass) {
201         return TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass);
202     }
203 
204     @Parameters(name = "{0}")
getParams()205     public static List<FlagsParameterization> getParams() {
206         return FlagsParameterization.allCombinationsOf(Flags.FLAG_EXPLICIT_KILL_FROM_SYSTEM_SERVER);
207     }
208 
AdapterServiceTest(FlagsParameterization flags)209     public AdapterServiceTest(FlagsParameterization flags) {
210         mSetFlagsRule = new SetFlagsRule(flags);
211     }
212 
213     @Before
setUp()214     public void setUp() throws PackageManager.NameNotFoundException {
215         Log.e(TAG, "setUp()");
216 
217         mLooper = new TestLooper();
218         Handler handler = new Handler(mLooper.getLooper());
219 
220         doReturn(mJniCallbacks).when(mNativeInterface).getCallbacks();
221 
222         AdapterNativeInterface.setInstance(mNativeInterface);
223         BluetoothKeystoreNativeInterface.setInstance(mKeystoreNativeInterface);
224         BluetoothQualityReportNativeInterface.setInstance(mQualityNativeInterface);
225         SdpManagerNativeInterface.setInstance(mSdpNativeInterface);
226         AdvertiseManagerNativeInterface.setInstance(mAdvertiseNativeInterface);
227         DistanceMeasurementNativeInterface.setInstance(mDistanceNativeInterface);
228         GattNativeInterface.setInstance(mGattNativeInterface);
229         PeriodicScanNativeInterface.setInstance(mPeriodicNativeInterface);
230         ScanNativeInterface.setInstance(mScanNativeInterface);
231 
232         // Post the creation of AdapterService since it rely on Looper.myLooper()
233         handler.post(() -> mAdapterService = new MockAdapterService(mLooper.getLooper()));
234         assertThat(mLooper.dispatchAll()).isEqualTo(1);
235         assertThat(mAdapterService).isNotNull();
236 
237         mMockPackageManager = mock(PackageManager.class);
238         when(mMockPackageManager.getPermissionInfo(any(), anyInt()))
239                 .thenReturn(new PermissionInfo());
240 
241         Context targetContext = InstrumentationRegistry.getTargetContext();
242 
243         mMockContentResolver = new MockContentResolver(targetContext);
244         mMockContentResolver.addProvider(
245                 Settings.AUTHORITY,
246                 new MockContentProvider() {
247                     @Override
248                     public Bundle call(String method, String request, Bundle args) {
249                         return Bundle.EMPTY;
250                     }
251                 });
252 
253         mBluetoothManager = targetContext.getSystemService(BluetoothManager.class);
254         mCompanionDeviceManager = targetContext.getSystemService(CompanionDeviceManager.class);
255         mDisplayManager = targetContext.getSystemService(DisplayManager.class);
256         mPermissionCheckerManager = targetContext.getSystemService(PermissionCheckerManager.class);
257         mPermissionManager = targetContext.getSystemService(PermissionManager.class);
258         mPowerManager = targetContext.getSystemService(PowerManager.class);
259 
260         when(mMockContext.getCacheDir()).thenReturn(targetContext.getCacheDir());
261         when(mMockContext.getUser()).thenReturn(targetContext.getUser());
262         when(mMockContext.getPackageName()).thenReturn(targetContext.getPackageName());
263         when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
264         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
265         when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
266         when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0))
267                 .thenReturn(mMockContext);
268         when(mMockContext.getResources()).thenReturn(mMockResources);
269         when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID);
270         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
271 
272         mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class);
273         mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class);
274         mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class);
275         DevicePolicyManager dpm =
276                 mockGetSystemService(Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class);
277         doReturn(false).when(dpm).isCommonCriteriaModeEnabled(any());
278         mockGetSystemService(Context.USER_SERVICE, UserManager.class);
279 
280         mockGetSystemService(
281                 Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class, mBatteryStatsManager);
282         mockGetSystemService(Context.BLUETOOTH_SERVICE, BluetoothManager.class, mBluetoothManager);
283         mockGetSystemService(
284                 Context.COMPANION_DEVICE_SERVICE,
285                 CompanionDeviceManager.class,
286                 mCompanionDeviceManager);
287         mockGetSystemService(Context.DISPLAY_SERVICE, DisplayManager.class, mDisplayManager);
288         mockGetSystemService(
289                 Context.PERMISSION_CHECKER_SERVICE,
290                 PermissionCheckerManager.class,
291                 mPermissionCheckerManager);
292         mockGetSystemService(
293                 Context.PERMISSION_SERVICE, PermissionManager.class, mPermissionManager);
294         mockGetSystemService(Context.POWER_SERVICE, PowerManager.class, mPowerManager);
295 
296         when(mMockContext.getSharedPreferences(anyString(), anyInt()))
297                 .thenReturn(
298                         targetContext.getSharedPreferences(
299                                 "AdapterServiceTestPrefs", Context.MODE_PRIVATE));
300 
301         doAnswer(
302                         invocation -> {
303                             Object[] args = invocation.getArguments();
304                             return targetContext.getDatabasePath((String) args[0]);
305                         })
306                 .when(mMockContext)
307                 .getDatabasePath(anyString());
308 
309         // Sets the foreground user id to match that of the tests (restored in tearDown)
310         mForegroundUserId = Utils.getForegroundUserId();
311         int callingUid = Binder.getCallingUid();
312         UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
313         Utils.setForegroundUserId(callingUser.getIdentifier());
314 
315         when(mIBluetoothCallback.asBinder()).thenReturn(mBinder);
316 
317         doReturn(Process.BLUETOOTH_UID)
318                 .when(mMockPackageManager)
319                 .getPackageUidAsUser(any(), anyInt(), anyInt());
320 
321         when(mMockGattService.getName()).thenReturn("GattService");
322         when(mMockService.getName()).thenReturn("Service1");
323         when(mMockService2.getName()).thenReturn("Service2");
324 
325         when(mMockMetricsLogger.init(any())).thenReturn(true);
326         when(mMockMetricsLogger.close()).thenReturn(true);
327 
328         configureEnabledProfiles();
329         Config.init(mMockContext);
330 
331         mAdapterService.setMetricsLogger(mMockMetricsLogger);
332 
333         // Attach a context to the service for permission checks.
334         mAdapterService.attach(mMockContext, null, null, null, mApplication, null);
335         mAdapterService.onCreate();
336 
337         mLooper.dispatchAll();
338 
339         mAdapterService.registerRemoteCallback(mIBluetoothCallback);
340     }
341 
342     @After
tearDown()343     public void tearDown() {
344         Log.e(TAG, "tearDown()");
345 
346         // Restores the foregroundUserId to the ID prior to the test setup
347         Utils.setForegroundUserId(mForegroundUserId);
348 
349         assertThat(mLooper.nextMessage()).isNull();
350         mAdapterService.cleanup();
351         mAdapterService.unregisterRemoteCallback(mIBluetoothCallback);
352         AdapterNativeInterface.setInstance(null);
353         BluetoothKeystoreNativeInterface.setInstance(null);
354         BluetoothQualityReportNativeInterface.setInstance(null);
355         SdpManagerNativeInterface.setInstance(null);
356         AdvertiseManagerNativeInterface.setInstance(null);
357         DistanceMeasurementNativeInterface.setInstance(null);
358         GattNativeInterface.setInstance(null);
359         PeriodicScanNativeInterface.setInstance(null);
360         ScanNativeInterface.setInstance(null);
361     }
362 
syncHandler(int... what)363     private void syncHandler(int... what) {
364         TestUtils.syncHandler(mLooper, what);
365     }
366 
dropNextMessage(int what)367     private void dropNextMessage(int what) {
368         Message msg = mLooper.nextMessage();
369         assertThat(msg).isNotNull();
370         assertWithMessage("Not the expected Message:\n" + msg).that(msg.what).isEqualTo(what);
371         Log.d(TAG, "Message dropped on purpose: " + msg);
372     }
373 
verifyStateChange(int prevState, int currState)374     private void verifyStateChange(int prevState, int currState) {
375         try {
376             verify(mIBluetoothCallback).onBluetoothStateChange(prevState, currState);
377         } catch (RemoteException e) {
378             // the mocked onBluetoothStateChange doesn't throw RemoteException
379         }
380     }
381 
verifyStateChange(int prevState, int currState, int timeoutMs)382     private void verifyStateChange(int prevState, int currState, int timeoutMs) {
383         try {
384             verify(mIBluetoothCallback, timeout(timeoutMs))
385                     .onBluetoothStateChange(prevState, currState);
386         } catch (RemoteException e) {
387             // the mocked onBluetoothStateChange doesn't throw RemoteException
388         }
389     }
390 
verifyStateChange(IBluetoothCallback cb, int prevState, int currState)391     private static void verifyStateChange(IBluetoothCallback cb, int prevState, int currState) {
392         try {
393             verify(cb).onBluetoothStateChange(prevState, currState);
394         } catch (RemoteException e) {
395             // the mocked onBluetoothStateChange doesn't throw RemoteException
396         }
397     }
398 
offToBleOn( TestLooper looper, ProfileService gattService, AdapterService adapter, Context ctx, IBluetoothCallback callback, AdapterNativeInterface nativeInterface)399     static void offToBleOn(
400             TestLooper looper,
401             ProfileService gattService,
402             AdapterService adapter,
403             Context ctx,
404             IBluetoothCallback callback,
405             AdapterNativeInterface nativeInterface) {
406         adapter.enable(false);
407         if (Flags.fastBindToApp()) {
408             TestUtils.syncHandler(looper, 0); // when fastBindToApp is enable init need to be run
409         }
410         TestUtils.syncHandler(looper, AdapterState.BLE_TURN_ON);
411         verifyStateChange(callback, STATE_OFF, STATE_BLE_TURNING_ON);
412 
413         if (!Flags.scanManagerRefactor()) {
414             TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_REGISTERED);
415 
416             TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
417         }
418 
419         verify(nativeInterface).enable();
420         adapter.stateChangeCallback(AbstractionLayer.BT_STATE_ON);
421         TestUtils.syncHandler(looper, AdapterState.BLE_STARTED);
422         verifyStateChange(callback, STATE_BLE_TURNING_ON, STATE_BLE_ON);
423         assertThat(adapter.getState()).isEqualTo(STATE_BLE_ON);
424     }
425 
onToBleOn( TestLooper looper, MockAdapterService adapter, Context ctx, IBluetoothCallback callback, boolean onlyGatt, List<ProfileService> services)426     static void onToBleOn(
427             TestLooper looper,
428             MockAdapterService adapter,
429             Context ctx,
430             IBluetoothCallback callback,
431             boolean onlyGatt,
432             List<ProfileService> services) {
433         adapter.disable();
434         TestUtils.syncHandler(looper, AdapterState.USER_TURN_OFF);
435         verifyStateChange(callback, STATE_ON, STATE_TURNING_OFF);
436 
437         if (!onlyGatt) {
438             // Stop PBAP and PAN services
439             assertThat(adapter.mSetProfileServiceStateCounter).isEqualTo(4);
440 
441             for (ProfileService service : services) {
442                 adapter.onProfileServiceStateChanged(service, STATE_OFF);
443                 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
444             }
445         }
446 
447         TestUtils.syncHandler(looper, AdapterState.BREDR_STOPPED);
448         verifyStateChange(callback, STATE_TURNING_OFF, STATE_BLE_ON);
449 
450         assertThat(adapter.getState()).isEqualTo(STATE_BLE_ON);
451     }
452 
doEnable(boolean onlyGatt)453     void doEnable(boolean onlyGatt) {
454         doEnable(
455                 mLooper,
456                 mMockGattService,
457                 mAdapterService,
458                 mMockContext,
459                 onlyGatt,
460                 List.of(mMockService, mMockService2),
461                 mNativeInterface);
462     }
463 
464     // Method is re-used in other AdapterService*Test
doEnable( TestLooper looper, ProfileService gattService, MockAdapterService adapter, Context ctx, boolean onlyGatt, List<ProfileService> services, AdapterNativeInterface nativeInterface)465     static void doEnable(
466             TestLooper looper,
467             ProfileService gattService,
468             MockAdapterService adapter,
469             Context ctx,
470             boolean onlyGatt,
471             List<ProfileService> services,
472             AdapterNativeInterface nativeInterface) {
473         Log.e(TAG, "doEnable() start");
474 
475         IBluetoothCallback callback = mock(IBluetoothCallback.class);
476         Binder binder = mock(Binder.class);
477         doReturn(binder).when(callback).asBinder();
478         adapter.registerRemoteCallback(callback);
479 
480         assertThat(adapter.getState()).isEqualTo(STATE_OFF);
481 
482         offToBleOn(looper, gattService, adapter, ctx, callback, nativeInterface);
483 
484         adapter.startBrEdr();
485         TestUtils.syncHandler(looper, AdapterState.USER_TURN_ON);
486         verifyStateChange(callback, STATE_BLE_ON, STATE_TURNING_ON);
487 
488         if (!onlyGatt) {
489             // Start Mock PBAP and PAN services
490             assertThat(adapter.mSetProfileServiceStateCounter).isEqualTo(2);
491 
492             for (ProfileService service : services) {
493                 adapter.addProfile(service);
494                 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_REGISTERED);
495             }
496             // Keep in 2 separate loop to first add the services and then eventually trigger the
497             // ON transition during the callback
498             for (ProfileService service : services) {
499                 adapter.onProfileServiceStateChanged(service, STATE_ON);
500                 TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
501             }
502         }
503         TestUtils.syncHandler(looper, AdapterState.BREDR_STARTED);
504         verifyStateChange(callback, STATE_TURNING_ON, STATE_ON);
505 
506         assertThat(adapter.getState()).isEqualTo(STATE_ON);
507         adapter.unregisterRemoteCallback(callback);
508         Log.e(TAG, "doEnable() complete success");
509     }
510 
doDisable(boolean onlyGatt)511     void doDisable(boolean onlyGatt) {
512         doDisable(
513                 mLooper,
514                 mAdapterService,
515                 mMockContext,
516                 onlyGatt,
517                 List.of(mMockService, mMockService2),
518                 mNativeInterface);
519     }
520 
doDisable( TestLooper looper, MockAdapterService adapter, Context ctx, boolean onlyGatt, List<ProfileService> services, AdapterNativeInterface nativeInterface)521     private static void doDisable(
522             TestLooper looper,
523             MockAdapterService adapter,
524             Context ctx,
525             boolean onlyGatt,
526             List<ProfileService> services,
527             AdapterNativeInterface nativeInterface) {
528         Log.e(TAG, "doDisable() start");
529         IBluetoothCallback callback = mock(IBluetoothCallback.class);
530         Binder binder = mock(Binder.class);
531         doReturn(binder).when(callback).asBinder();
532         adapter.registerRemoteCallback(callback);
533 
534         assertThat(adapter.getState()).isEqualTo(STATE_ON);
535 
536         onToBleOn(looper, adapter, ctx, callback, onlyGatt, services);
537 
538         adapter.stopBle();
539         TestUtils.syncHandler(looper, AdapterState.BLE_TURN_OFF);
540         verifyStateChange(callback, STATE_BLE_ON, STATE_BLE_TURNING_OFF);
541 
542         TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
543         TestUtils.syncHandler(looper, MESSAGE_PROFILE_SERVICE_UNREGISTERED);
544 
545         verify(nativeInterface).disable();
546         adapter.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
547         TestUtils.syncHandler(looper, AdapterState.BLE_STOPPED);
548         if (Flags.explicitKillFromSystemServer()) {
549             // When reaching the OFF state, the cleanup is called that will destroy the state
550             // machine of the adapterService. Destroying state machine send a -1 event on the
551             // handler
552             TestUtils.syncHandler(looper, -1);
553         }
554         verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF);
555 
556         assertThat(adapter.getState()).isEqualTo(STATE_OFF);
557         adapter.unregisterRemoteCallback(callback);
558         Log.e(TAG, "doDisable() complete success");
559     }
560 
561     /** Test: Turn Bluetooth on. Check whether the AdapterService gets started. */
562     @Test
testEnable()563     public void testEnable() {
564         doEnable(false);
565     }
566 
567     @Test
enable_isCorrectScanMode()568     public void enable_isCorrectScanMode() {
569         doEnable(false);
570 
571         final int expectedScanMode = BluetoothAdapter.SCAN_MODE_CONNECTABLE;
572 
573         int type = AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE;
574         byte[] val = Utils.intToByteArray(AdapterService.convertScanModeToHal(expectedScanMode));
575 
576         verify(mNativeInterface).setAdapterProperty(eq(type), eq(val));
577         // Intercept native call and simulate its callback
578         mAdapterService.mAdapterProperties.adapterPropertyChangedCallback(
579                 new int[] {type}, new byte[][] {val});
580         assertThat(mAdapterService.getScanMode()).isEqualTo(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
581     }
582 
583     /** Test: Turn Bluetooth on/off. Check whether the AdapterService gets started and stopped. */
584     @Test
testEnableDisable()585     public void testEnableDisable() {
586         doEnable(false);
587         doDisable(false);
588     }
589 
590     /**
591      * Test: Turn Bluetooth on/off with only GATT supported. Check whether the AdapterService gets
592      * started and stopped.
593      */
594     @Test
testEnableDisableOnlyGatt()595     public void testEnableDisableOnlyGatt() {
596         Context mockContext = mock(Context.class);
597         Resources mockResources = mock(Resources.class);
598 
599         when(mockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
600         when(mockContext.getContentResolver()).thenReturn(mMockContentResolver);
601         when(mockContext.getApplicationContext()).thenReturn(mockContext);
602         when(mockContext.getResources()).thenReturn(mockResources);
603         when(mockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID);
604         when(mockContext.getPackageManager()).thenReturn(mMockPackageManager);
605 
606         // Config is set to PBAP, PAN and GATT by default. Turn off PAN and PBAP.
607         Config.setProfileEnabled(BluetoothProfile.PAN, false);
608         Config.setProfileEnabled(BluetoothProfile.PBAP, false);
609 
610         Config.init(mockContext);
611         doEnable(true);
612         doDisable(true);
613     }
614 
615     /** Test: Don't start GATT Check whether the AdapterService quits gracefully */
616     @Test
testGattStartTimeout()617     public void testGattStartTimeout() {
618         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
619 
620         mAdapterService.enable(false);
621         if (Flags.fastBindToApp()) {
622             syncHandler(0); // when fastBindToApp is enable init need to be run
623         }
624         syncHandler(AdapterState.BLE_TURN_ON);
625         verifyStateChange(STATE_OFF, STATE_BLE_TURNING_ON);
626         assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
627         syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED);
628 
629         // Fetch next message and never process it to simulate a timeout.
630         dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
631 
632         mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
633         syncHandler(AdapterState.BLE_START_TIMEOUT);
634         assertThat(mAdapterService.getBluetoothGatt()).isNull();
635 
636         syncHandler(AdapterState.BLE_STOPPED);
637         if (Flags.explicitKillFromSystemServer()) {
638             // When reaching the OFF state, the cleanup is called that will destroy the state
639             // machine of the adapterService. Destroying state machine send a -1 event on the
640             // handler
641             syncHandler(-1);
642         }
643         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
644         syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
645 
646         verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
647         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
648     }
649 
650     /** Test: Don't stop GATT Check whether the AdapterService quits gracefully */
651     @Test
testGattStopTimeout()652     public void testGattStopTimeout() {
653         doEnable(false);
654 
655         onToBleOn(
656                 mLooper,
657                 mAdapterService,
658                 mMockContext,
659                 mIBluetoothCallback,
660                 false,
661                 List.of(mMockService, mMockService2));
662 
663         mAdapterService.stopBle();
664         syncHandler(AdapterState.BLE_TURN_OFF);
665         verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS);
666         assertThat(mAdapterService.getBluetoothGatt()).isNull();
667 
668         // Fetch Gatt message and never process it to simulate a timeout.
669         dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
670         dropNextMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
671 
672         mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
673         syncHandler(AdapterState.BLE_STOP_TIMEOUT);
674         if (Flags.explicitKillFromSystemServer()) {
675             // When reaching the OFF state, the cleanup is called that will destroy the state
676             // machine of the adapterService. Destroying state machine send a -1 event on the
677             // handler
678             syncHandler(-1);
679         }
680         verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
681 
682         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
683     }
684 
685     @Test
686     @DisableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR)
startBleOnly_whenScanManagerRefactorFlagIsOff_onlyStartGattProfile()687     public void startBleOnly_whenScanManagerRefactorFlagIsOff_onlyStartGattProfile() {
688         mAdapterService.bringUpBle();
689 
690         assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
691         assertThat(mAdapterService.getBluetoothScan()).isNull();
692 
693         dropNextMessage(MESSAGE_PROFILE_SERVICE_REGISTERED);
694         dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
695     }
696 
697     @Test
698     @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR)
startBleOnly_whenScanManagerRefactorFlagIsOn_onlyStartScanController()699     public void startBleOnly_whenScanManagerRefactorFlagIsOn_onlyStartScanController() {
700         mAdapterService.bringUpBle();
701 
702         assertThat(mAdapterService.getBluetoothGatt()).isNull();
703         assertThat(mAdapterService.getBluetoothScan()).isNotNull();
704     }
705 
706     @Test
707     @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR)
startBleOnly_whenScanManagerRefactorFlagIsOn_startAndStopScanController()708     public void startBleOnly_whenScanManagerRefactorFlagIsOn_startAndStopScanController() {
709         assertThat(mAdapterService.getBluetoothScan()).isNull();
710         assertThat(mAdapterService.getBluetoothGatt()).isNull();
711 
712         IBluetoothCallback callback = mock(IBluetoothCallback.class);
713         Binder binder = mock(Binder.class);
714         doReturn(binder).when(callback).asBinder();
715         mAdapterService.registerRemoteCallback(callback);
716 
717         offToBleOn(
718                 mLooper,
719                 mMockGattService,
720                 mAdapterService,
721                 mMockContext,
722                 mIBluetoothCallback,
723                 mNativeInterface);
724 
725         assertThat(mAdapterService.getBluetoothScan()).isNotNull();
726         assertThat(mAdapterService.getBluetoothGatt()).isNull();
727 
728         mAdapterService.stopBle();
729         syncHandler(AdapterState.BLE_TURN_OFF);
730         verifyStateChange(callback, STATE_BLE_ON, STATE_BLE_TURNING_OFF);
731 
732         verify(mNativeInterface).disable();
733         mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
734         syncHandler(AdapterState.BLE_STOPPED);
735         if (Flags.explicitKillFromSystemServer()) {
736             // When reaching the OFF state, the cleanup is called that will destroy the state
737             // machine of the adapterService. Destroying state machine send a -1 event on the
738             // handler
739             syncHandler(-1);
740         }
741         verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF);
742 
743         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
744         mAdapterService.unregisterRemoteCallback(callback);
745 
746         assertThat(mAdapterService.getBluetoothScan()).isNull();
747         assertThat(mAdapterService.getBluetoothGatt()).isNull();
748     }
749 
750     @Test
751     @EnableFlags(Flags.FLAG_SCAN_MANAGER_REFACTOR)
startBrDr_whenScanManagerRefactorFlagIsOn_startAndStopScanController()752     public void startBrDr_whenScanManagerRefactorFlagIsOn_startAndStopScanController() {
753         assertThat(mAdapterService.getBluetoothScan()).isNull();
754         assertThat(mAdapterService.getBluetoothGatt()).isNull();
755 
756         IBluetoothCallback callback = mock(IBluetoothCallback.class);
757         Binder binder = mock(Binder.class);
758         doReturn(binder).when(callback).asBinder();
759         mAdapterService.registerRemoteCallback(callback);
760 
761         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
762 
763         offToBleOn(
764                 mLooper,
765                 mMockGattService,
766                 mAdapterService,
767                 mMockContext,
768                 mIBluetoothCallback,
769                 mNativeInterface);
770 
771         assertThat(mAdapterService.getBluetoothScan()).isNotNull();
772         assertThat(mAdapterService.getBluetoothGatt()).isNull();
773 
774         mAdapterService.startBrEdr();
775         TestUtils.syncHandler(mLooper, AdapterState.USER_TURN_ON);
776         verifyStateChange(callback, STATE_BLE_ON, STATE_TURNING_ON);
777 
778         // Start Mock PBAP, PAN, and GATT services
779         assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(3);
780         List<ProfileService> services = List.of(mMockService, mMockService2, mMockGattService);
781 
782         for (ProfileService service : services) {
783             mAdapterService.addProfile(service);
784             TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_REGISTERED);
785         }
786 
787         for (ProfileService service : services) {
788             mAdapterService.onProfileServiceStateChanged(service, STATE_ON);
789             TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
790         }
791 
792         TestUtils.syncHandler(mLooper, AdapterState.BREDR_STARTED);
793         verifyStateChange(callback, STATE_TURNING_ON, STATE_ON);
794 
795         assertThat(mAdapterService.getState()).isEqualTo(STATE_ON);
796 
797         mAdapterService.disable();
798         TestUtils.syncHandler(mLooper, AdapterState.USER_TURN_OFF);
799         verifyStateChange(callback, STATE_ON, STATE_TURNING_OFF);
800 
801         // Stop PBAP, PAN, and GATT services
802         assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(6);
803 
804         for (ProfileService service : services) {
805             mAdapterService.onProfileServiceStateChanged(service, STATE_OFF);
806             TestUtils.syncHandler(mLooper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
807         }
808 
809         TestUtils.syncHandler(mLooper, AdapterState.BREDR_STOPPED);
810         verifyStateChange(callback, STATE_TURNING_OFF, STATE_BLE_ON);
811 
812         assertThat(mAdapterService.getState()).isEqualTo(STATE_BLE_ON);
813 
814         mAdapterService.unregisterRemoteCallback(callback);
815     }
816 
817     /** Test: Don't start a classic profile Check whether the AdapterService quits gracefully */
818     @Test
testProfileStartTimeout()819     public void testProfileStartTimeout() {
820         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
821 
822         offToBleOn(
823                 mLooper,
824                 mMockGattService,
825                 mAdapterService,
826                 mMockContext,
827                 mIBluetoothCallback,
828                 mNativeInterface);
829 
830         mAdapterService.startBrEdr();
831         syncHandler(AdapterState.USER_TURN_ON);
832         verifyStateChange(STATE_BLE_ON, STATE_TURNING_ON);
833         assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(2);
834 
835         mAdapterService.addProfile(mMockService);
836         syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED);
837         mAdapterService.addProfile(mMockService2);
838         syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED);
839         mAdapterService.onProfileServiceStateChanged(mMockService, STATE_ON);
840         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
841 
842         // Skip onProfileServiceStateChanged for mMockService2 to be in the test situation
843 
844         mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
845         syncHandler(AdapterState.BREDR_START_TIMEOUT);
846 
847         verifyStateChange(STATE_TURNING_ON, STATE_TURNING_OFF);
848         assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(4);
849 
850         mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF);
851         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
852         syncHandler(AdapterState.BREDR_STOPPED);
853         verifyStateChange(STATE_TURNING_OFF, STATE_BLE_ON);
854 
855         // Ensure GATT is still running
856         assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
857     }
858 
859     /** Test: Don't stop a classic profile Check whether the AdapterService quits gracefully */
860     @Test
testProfileStopTimeout()861     public void testProfileStopTimeout() {
862         doEnable(false);
863 
864         mAdapterService.disable();
865         syncHandler(AdapterState.USER_TURN_OFF);
866         verifyStateChange(STATE_ON, STATE_TURNING_OFF);
867         assertThat(mAdapterService.mSetProfileServiceStateCounter).isEqualTo(4);
868 
869         mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF);
870         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
871 
872         // Skip onProfileServiceStateChanged for mMockService2 to be in the test situation
873 
874         mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
875         syncHandler(AdapterState.BREDR_STOP_TIMEOUT);
876         verifyStateChange(STATE_TURNING_OFF, STATE_BLE_TURNING_OFF);
877 
878         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
879         syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
880 
881         // TODO(b/280518177): The only timeout to fire here should be the BREDR
882         mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
883         syncHandler(AdapterState.BLE_STOP_TIMEOUT);
884         if (Flags.explicitKillFromSystemServer()) {
885             // When reaching the OFF state, the cleanup is called that will destroy the state
886             // machine of the adapterService. Destroying state machine send a -1 event on the
887             // handler
888             syncHandler(-1);
889         }
890         verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
891 
892         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
893     }
894 
895     /** Test: Toggle snoop logging setting Check whether the AdapterService restarts fully */
896     @Test
testSnoopLoggingChange()897     public void testSnoopLoggingChange() {
898         BluetoothProperties.snoop_log_mode_values snoopSetting =
899                 BluetoothProperties.snoop_log_mode()
900                         .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY);
901         BluetoothProperties.snoop_log_mode(BluetoothProperties.snoop_log_mode_values.DISABLED);
902         doEnable(false);
903 
904         assertThat(
905                         BluetoothProperties.snoop_log_mode()
906                                 .orElse(BluetoothProperties.snoop_log_mode_values.EMPTY))
907                 .isNotEqualTo(BluetoothProperties.snoop_log_mode_values.FULL);
908 
909         BluetoothProperties.snoop_log_mode(BluetoothProperties.snoop_log_mode_values.FULL);
910 
911         onToBleOn(
912                 mLooper,
913                 mAdapterService,
914                 mMockContext,
915                 mIBluetoothCallback,
916                 false,
917                 List.of(mMockService, mMockService2));
918 
919         // Do not call stopBle().  The Adapter should turn itself off.
920         syncHandler(AdapterState.BLE_TURN_OFF);
921         verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS);
922 
923         syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); // stop GATT
924         syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
925 
926         verify(mNativeInterface).disable();
927 
928         mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
929         syncHandler(AdapterState.BLE_STOPPED);
930         if (Flags.explicitKillFromSystemServer()) {
931             // When reaching the OFF state, the cleanup is called that will destroy the state
932             // machine of the adapterService. Destroying state machine send a -1 event on the
933             // handler
934             syncHandler(-1);
935         }
936 
937         verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
938         assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
939 
940         // Restore earlier setting
941         BluetoothProperties.snoop_log_mode(snoopSetting);
942     }
943 
944     /**
945      * Test: Obfuscate a null Bluetooth Check if returned value from {@link
946      * AdapterService#obfuscateAddress(BluetoothDevice)} is an empty array when device address is
947      * null
948      */
949     @Test
testObfuscateBluetoothAddress_NullAddress()950     public void testObfuscateBluetoothAddress_NullAddress() {
951         assertThat(mAdapterService.obfuscateAddress(null)).isEmpty();
952     }
953 
954     @Test
testAddressConsolidation()955     public void testAddressConsolidation() {
956         // Create device properties
957         RemoteDevices remoteDevices = mAdapterService.getRemoteDevices();
958         remoteDevices.addDeviceProperties(Utils.getBytesFromAddress((TEST_BT_ADDR_1)));
959         String identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1);
960         if (!Flags.identityAddressNullIfUnknown()) {
961             assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_1);
962         }
963 
964         // Trigger address consolidate callback
965         remoteDevices.addressConsolidateCallback(
966                 Utils.getBytesFromAddress(TEST_BT_ADDR_1),
967                 Utils.getBytesFromAddress(TEST_BT_ADDR_2));
968 
969         // Verify we can get correct identity address
970         identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1);
971         assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_2);
972     }
973 
974     @Test
975     @EnableFlags(Flags.FLAG_IDENTITY_ADDRESS_NULL_IF_UNKNOWN)
testIdentityAddressNullIfUnknown()976     public void testIdentityAddressNullIfUnknown() {
977         BluetoothDevice device = TestUtils.getTestDevice(BluetoothAdapter.getDefaultAdapter(), 0);
978 
979         assertThat(mAdapterService.getByteIdentityAddress(device)).isNull();
980         assertThat(mAdapterService.getIdentityAddress(device.getAddress())).isNull();
981     }
982 
getMetricsSalt(Map<String, Map<String, String>> adapterConfig)983     public static byte[] getMetricsSalt(Map<String, Map<String, String>> adapterConfig) {
984         Map<String, String> metricsSection = adapterConfig.get("Metrics");
985         if (metricsSection == null) {
986             Log.e(TAG, "Metrics section is null: " + adapterConfig.toString());
987             return null;
988         }
989         String saltString = metricsSection.get("Salt256Bit");
990         if (saltString == null) {
991             Log.e(TAG, "Salt256Bit is null: " + metricsSection.toString());
992             return null;
993         }
994         byte[] metricsSalt = HexEncoding.decode(saltString, false /* allowSingleChar */);
995         if (metricsSalt.length != 32) {
996             Log.e(TAG, "Salt length is not 32 bit, but is " + metricsSalt.length);
997             return null;
998         }
999         return metricsSalt;
1000     }
1001 
obfuscateInJava(byte[] key, BluetoothDevice device)1002     public static byte[] obfuscateInJava(byte[] key, BluetoothDevice device) {
1003         String algorithm = "HmacSHA256";
1004         try {
1005             Mac hmac256 = Mac.getInstance(algorithm);
1006             hmac256.init(new SecretKeySpec(key, algorithm));
1007             return hmac256.doFinal(Utils.getByteAddress(device));
1008         } catch (NoSuchAlgorithmException | IllegalStateException | InvalidKeyException exp) {
1009             exp.printStackTrace();
1010             return null;
1011         }
1012     }
1013 
isByteArrayAllZero(byte[] byteArray)1014     public static boolean isByteArrayAllZero(byte[] byteArray) {
1015         for (byte i : byteArray) {
1016             if (i != 0) {
1017                 return false;
1018             }
1019         }
1020         return true;
1021     }
1022 
1023     /**
1024      * Test: Get id for null address Check if returned value from {@link
1025      * AdapterService#getMetricId(BluetoothDevice)} is 0 when device address is null
1026      */
1027     @Test
testGetMetricId_NullAddress()1028     public void testGetMetricId_NullAddress() {
1029         assertThat(mAdapterService.getMetricId(null)).isEqualTo(0);
1030     }
1031 
1032     @Test
testDump_doesNotCrash()1033     public void testDump_doesNotCrash() {
1034         FileDescriptor fd = new FileDescriptor();
1035         PrintWriter writer = mock(PrintWriter.class);
1036 
1037         mAdapterService.dump(fd, writer, new String[] {});
1038         mAdapterService.dump(fd, writer, new String[] {"set-test-mode", "enabled"});
1039         doReturn(new byte[0]).when(mNativeInterface).dumpMetrics();
1040         mAdapterService.dump(fd, writer, new String[] {"--proto-bin"});
1041         mAdapterService.dump(fd, writer, new String[] {"random", "arguments"});
1042     }
1043 }
1044