1 /*
2  * Copyright 2022 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.bluetooth.btservice;
17 
18 import android.bluetooth.BluetoothAdapter;
19 import android.util.Log;
20 
21 import com.android.bluetooth.Utils;
22 import com.android.internal.annotations.VisibleForTesting;
23 
24 /**
25  * A proxy class that facilitates testing of the ScanManager.
26  *
27  * <p>This is necessary due to the "final" attribute of the BluetoothAdapter class. In order to test
28  * the correct functioning of the ScanManager class, the final class must be put into a container
29  * that can be mocked correctly.
30  */
31 public class BluetoothAdapterProxy {
32     private static final String TAG = BluetoothAdapterProxy.class.getSimpleName();
33     private static BluetoothAdapterProxy sInstance;
34     private static final Object INSTANCE_LOCK = new Object();
35 
BluetoothAdapterProxy()36     private BluetoothAdapterProxy() {}
37 
38     /**
39      * Get the singleton instance of proxy.
40      *
41      * @return the singleton instance, guaranteed not null
42      */
getInstance()43     public static BluetoothAdapterProxy getInstance() {
44         synchronized (INSTANCE_LOCK) {
45             if (sInstance == null) {
46                 sInstance = new BluetoothAdapterProxy();
47             }
48             return sInstance;
49         }
50     }
51 
52     /**
53      * Proxy function that calls {@link BluetoothAdapter#isOffloadedFilteringSupported()}.
54      *
55      * @return whether the offloaded scan filtering is supported
56      */
isOffloadedScanFilteringSupported()57     public boolean isOffloadedScanFilteringSupported() {
58         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
59         return adapter.isOffloadedFilteringSupported();
60     }
61 
62     /**
63      * Allow unit tests to substitute BluetoothAdapterProxy with a test instance
64      *
65      * @param proxy a test instance of the BluetoothAdapterProxy
66      */
67     @VisibleForTesting
setInstanceForTesting(BluetoothAdapterProxy proxy)68     public static void setInstanceForTesting(BluetoothAdapterProxy proxy) {
69         Utils.enforceInstrumentationTestMode();
70         synchronized (INSTANCE_LOCK) {
71             Log.d(TAG, "setInstanceForTesting(), set to " + proxy);
72             sInstance = proxy;
73         }
74     }
75 }
76