• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.settingslib.bluetooth;
18 
19 import android.content.Context;
20 import android.os.Handler;
21 import android.os.UserHandle;
22 import android.util.Log;
23 
24 import androidx.annotation.Nullable;
25 import androidx.annotation.RequiresPermission;
26 
27 import java.lang.ref.WeakReference;
28 
29 /**
30  * LocalBluetoothManager provides a simplified interface on top of a subset of
31  * the Bluetooth API. Note that {@link #getInstance} will return null
32  * if there is no Bluetooth adapter on this device, and callers must be
33  * prepared to handle this case.
34  */
35 public class LocalBluetoothManager {
36     private static final String TAG = "LocalBluetoothManager";
37 
38     /** Singleton instance. */
39     private static LocalBluetoothManager sInstance;
40 
41     private final Context mContext;
42 
43     /** If a BT-related activity is in the foreground, this will be it. */
44     private WeakReference<Context> mForegroundActivity;
45 
46     private final LocalBluetoothAdapter mLocalAdapter;
47 
48     private final CachedBluetoothDeviceManager mCachedDeviceManager;
49 
50     /** The Bluetooth profile manager. */
51     private final LocalBluetoothProfileManager mProfileManager;
52 
53     /** The broadcast receiver event manager. */
54     private final BluetoothEventManager mEventManager;
55 
56     @Nullable
getInstance(Context context, BluetoothManagerCallback onInitCallback)57     public static synchronized LocalBluetoothManager getInstance(Context context,
58             BluetoothManagerCallback onInitCallback) {
59         if (sInstance == null) {
60             LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
61             if (adapter == null) {
62                 return null;
63             }
64             // This will be around as long as this process is
65             sInstance = new LocalBluetoothManager(adapter, context, /* handler= */ null,
66                     /* userHandle= */ null);
67             if (onInitCallback != null) {
68                 onInitCallback.onBluetoothManagerInitialized(context.getApplicationContext(),
69                         sInstance);
70             }
71         }
72 
73         return sInstance;
74     }
75 
76     /**
77      * Returns a new instance of {@link LocalBluetoothManager} or null if Bluetooth is not
78      * supported for this hardware. This instance should be globally cached by the caller.
79      */
80     @Nullable
create(Context context, Handler handler)81     public static LocalBluetoothManager create(Context context, Handler handler) {
82         LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
83         if (adapter == null) {
84             return null;
85         }
86         return new LocalBluetoothManager(adapter, context, handler, /* userHandle= */ null);
87     }
88 
89     /**
90      * Returns a new instance of {@link LocalBluetoothManager} or null if Bluetooth is not
91      * supported for this hardware. This instance should be globally cached by the caller.
92      *
93      * <p> Allows to specify a {@link UserHandle} for which to receive bluetooth events.
94      *
95      * <p> Requires {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission.
96      */
97     @Nullable
98     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
create(Context context, Handler handler, UserHandle userHandle)99     public static LocalBluetoothManager create(Context context, Handler handler,
100             UserHandle userHandle) {
101         LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
102         if (adapter == null) {
103             return null;
104         }
105         return new LocalBluetoothManager(adapter, context, handler,
106                 userHandle);
107     }
108 
LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context, Handler handler, UserHandle userHandle)109     private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context, Handler handler,
110             UserHandle userHandle) {
111         mContext = context.getApplicationContext();
112         mLocalAdapter = adapter;
113         mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, this);
114         mEventManager =
115                 new BluetoothEventManager(
116                         mLocalAdapter,
117                         this,
118                         mCachedDeviceManager,
119                         mContext,
120                         handler,
121                         userHandle);
122         mProfileManager =
123                 new LocalBluetoothProfileManager(
124                         mContext, mLocalAdapter, mCachedDeviceManager, mEventManager);
125 
126         mProfileManager.updateLocalProfiles();
127         mEventManager.readPairedDevices();
128     }
129 
getBluetoothAdapter()130     public LocalBluetoothAdapter getBluetoothAdapter() {
131         return mLocalAdapter;
132     }
133 
getContext()134     public Context getContext() {
135         return mContext;
136     }
137 
getForegroundActivity()138     public Context getForegroundActivity() {
139         return mForegroundActivity == null
140                 ? null
141                 : mForegroundActivity.get();
142     }
143 
isForegroundActivity()144     public boolean isForegroundActivity() {
145         return mForegroundActivity != null && mForegroundActivity.get() != null;
146     }
147 
setForegroundActivity(Context context)148     public synchronized void setForegroundActivity(Context context) {
149         if (context != null) {
150             Log.d(TAG, "setting foreground activity to non-null context");
151             mForegroundActivity = new WeakReference<>(context);
152         } else {
153             if (mForegroundActivity != null) {
154                 Log.d(TAG, "setting foreground activity to null");
155                 mForegroundActivity = null;
156             }
157         }
158     }
159 
getCachedDeviceManager()160     public CachedBluetoothDeviceManager getCachedDeviceManager() {
161         return mCachedDeviceManager;
162     }
163 
getEventManager()164     public BluetoothEventManager getEventManager() {
165         return mEventManager;
166     }
167 
getProfileManager()168     public LocalBluetoothProfileManager getProfileManager() {
169         return mProfileManager;
170     }
171 
172     public interface BluetoothManagerCallback {
onBluetoothManagerInitialized(Context appContext, LocalBluetoothManager bluetoothManager)173         void onBluetoothManagerInitialized(Context appContext,
174                 LocalBluetoothManager bluetoothManager);
175     }
176 }
177