blob: c4bc52c6f4de472ede1dd1d93e26c5ac5030d34f [file] [log] [blame]
fredc0f420372012-04-12 00:02:00 -07001/*
Zhihai Xufa0fd392012-10-23 17:31:56 -07002 * Copyright (C) 2012 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.
fredc0f420372012-04-12 00:02:00 -070015 */
16
17package com.android.server;
18
Svet Ganov408abf72015-05-12 19:13:36 -070019import android.Manifest;
Zhihai Xu40874a02012-10-08 17:57:03 -070020import android.app.ActivityManager;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010021import android.app.AppGlobals;
fredc0f420372012-04-12 00:02:00 -070022import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000023import android.bluetooth.BluetoothProfile;
Jack He8caab152018-03-02 13:08:36 -080024import android.bluetooth.BluetoothProtoEnums;
fredc0f420372012-04-12 00:02:00 -070025import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070026import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070027import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000028import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070029import android.bluetooth.IBluetoothManager;
30import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000031import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070032import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070033import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070034import android.content.BroadcastReceiver;
35import android.content.ComponentName;
36import android.content.ContentResolver;
37import android.content.Context;
38import android.content.Intent;
39import android.content.IntentFilter;
40import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070041import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010042import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070043import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000044import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070045import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070046import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010047import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070048import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070049import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070050import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070051import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070052import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070053import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070054import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070055import android.os.SystemClock;
Stanley Tngfe8c8332018-06-19 08:48:10 -070056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000058import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010059import android.os.UserManagerInternal;
60import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070061import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070062import android.provider.Settings.SettingNotFoundException;
Stanley Tngfe8c8332018-06-19 08:48:10 -070063import android.text.TextUtils;
64import android.util.FeatureFlagUtils;
65import android.util.Log;
Jeff Sharkey67609c72016-03-05 14:29:13 -070066import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000067import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070068
Arthur Hsuf3f95a92018-01-11 16:46:22 -080069import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060070import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010071import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010072
Mike Lockwood726d4de2014-10-28 14:06:28 -070073import java.io.FileDescriptor;
74import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000075import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080076import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080077import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000078import java.util.Map;
Chienyuan177156b2018-12-18 10:40:25 +080079import java.util.NoSuchElementException;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010080import java.util.concurrent.ConcurrentHashMap;
81import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070082
Marie Janssen59804562016-12-28 14:13:21 -080083
fredc0f420372012-04-12 00:02:00 -070084class BluetoothManagerService extends IBluetoothManager.Stub {
85 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070086 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070087
fredc0f420372012-04-12 00:02:00 -070088 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
89 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070090
Myles Watsonb5cd11a2017-11-27 16:42:11 -080091 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
92 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
93 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070094
95 private static final int ACTIVE_LOG_MAX_SIZE = 20;
96 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070097
fredc0f420372012-04-12 00:02:00 -070098 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053099 //Maximum msec to wait for service restart
100 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800101 //Maximum msec to wait for restart due to error
102 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700103 //Maximum msec to delay MESSAGE_USER_SWITCHED
104 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000105 // Delay for the addProxy function in msec
106 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700107
108 private static final int MESSAGE_ENABLE = 1;
109 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700110 private static final int MESSAGE_REGISTER_ADAPTER = 20;
111 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
112 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
113 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
114 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
115 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530116 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700117 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
118 private static final int MESSAGE_TIMEOUT_BIND = 100;
119 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700120 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700121 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700122 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000123 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
124 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700125 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
126
127 private static final int RESTORE_SETTING_TO_ON = 1;
128 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800129
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700130 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800131
Zhihai Xu401202b2012-12-03 11:36:21 -0800132 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800133 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800134 // Bluetooth persisted setting is on
135 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800136 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800137 // Bluetooth persisted setting is on
138 // but Airplane mode will affect Bluetooth state at start up
139 // and Airplane mode will have higher priority.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800140 private static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700141
Matthew Xieddf7e472013-03-01 18:41:02 -0800142 private static final int SERVICE_IBLUETOOTH = 1;
143 private static final int SERVICE_IBLUETOOTHGATT = 2;
144
fredc0f420372012-04-12 00:02:00 -0700145 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700146
147 // Locks are not provided for mName and mAddress.
148 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700149 private String mAddress;
150 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700151 private final ContentResolver mContentResolver;
152 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
153 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800154 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700155 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800156 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800157 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700158 private boolean mBinding;
159 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800160
Zhihai Xu401202b2012-12-03 11:36:21 -0800161 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700162 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800163 private boolean mEnable;
164
Jack He8caab152018-03-02 13:08:36 -0800165 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700166 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
167 }
168
Marie Janssen59804562016-12-28 14:13:21 -0800169 /**
170 * Used for tracking apps that enabled / disabled Bluetooth.
171 */
172 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800173 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800174 private String mPackageName;
175 private boolean mEnable;
176 private long mTimestamp;
177
Jack He8caab152018-03-02 13:08:36 -0800178 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
179 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800180 mPackageName = packageName;
181 mEnable = enable;
182 mTimestamp = timestamp;
183 }
184
Marie Janssen59804562016-12-28 14:13:21 -0800185 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800186 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
187 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800188 }
189
190 }
191
Jack He8caab152018-03-02 13:08:36 -0800192 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
193 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700194 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700195 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800196
197 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800198 // synchronize with broadcast receiver.
199 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800200 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800201
202 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800203 private Map<IBinder, ClientDeathRecipient> mBleApps =
204 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800205
Zhihai Xu40874a02012-10-08 17:57:03 -0700206 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700207 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800208 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200209 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700210
Stanley Tng61dbd812019-01-13 16:04:31 -0800211 private boolean mIsHearingAidProfileSupported;
212
Benjamin Franze8b98922014-11-12 15:57:54 +0000213 // Save a ProfileServiceConnections object for each of the bound
214 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800215 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000216
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700217 private final boolean mWirelessConsentRequired;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700218
Marie Janssen59804562016-12-28 14:13:21 -0800219 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700220 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800221 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
222 Message msg =
223 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700224 mHandler.sendMessage(msg);
225 }
226 };
227
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100228 private final UserRestrictionsListener mUserRestrictionsListener =
229 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800230 @Override
231 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
232 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700233
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800234 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
235 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
236 updateOppLauncherComponentState(userId,
237 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
238 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100239
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800240 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
241 if (userId == UserHandle.USER_SYSTEM
242 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
243 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
244 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
245 UserManager.DISALLOW_BLUETOOTH)) {
246 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800247 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
248 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800249 } else {
250 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
251 UserManager.DISALLOW_BLUETOOTH_SHARING));
252 }
253 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100254 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800255 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100256
Ajay Panicker467bc042017-02-22 12:23:15 -0800257 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
258 @Override
259 public void onChange(boolean unused) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800260 synchronized (this) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800261 if (isBluetoothPersistedStateOn()) {
262 if (isAirplaneModeOn()) {
263 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
264 } else {
265 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
266 }
267 }
268
269 int st = BluetoothAdapter.STATE_OFF;
270 try {
271 mBluetoothLock.readLock().lock();
272 if (mBluetooth != null) {
273 st = mBluetooth.getState();
274 }
275 } catch (RemoteException e) {
276 Slog.e(TAG, "Unable to call getState", e);
277 return;
278 } finally {
279 mBluetoothLock.readLock().unlock();
280 }
281
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800282 Slog.d(TAG,
283 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
Rene Mayrhofer7d6c8e52018-11-28 11:32:40 -0800284 st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
Ajay Panicker467bc042017-02-22 12:23:15 -0800285
286 if (isAirplaneModeOn()) {
287 // Clear registered LE apps to force shut-off
288 clearBleApps();
289
290 // If state is BLE_ON make sure we trigger disableBLE
291 if (st == BluetoothAdapter.STATE_BLE_ON) {
292 try {
293 mBluetoothLock.readLock().lock();
294 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700295 addActiveLog(
296 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
297 mContext.getPackageName(), false);
Ajay Panicker467bc042017-02-22 12:23:15 -0800298 mBluetooth.onBrEdrDown();
299 mEnable = false;
300 mEnableExternal = false;
301 }
302 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800303 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800304 } finally {
305 mBluetoothLock.readLock().unlock();
306 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800307 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800308 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
309 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800310 }
311 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800312 sendEnableMsg(mQuietEnableExternal,
313 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
314 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800315 }
316 }
317 }
318 };
319
fredcbf072a72012-05-09 16:52:50 -0700320 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700321 @Override
322 public void onReceive(Context context, Intent intent) {
323 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700324 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700325 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800326 if (DBG) {
327 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
328 }
fredc0f420372012-04-12 00:02:00 -0700329 if (newName != null) {
330 storeNameAndAddress(newName, null);
331 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700332 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
333 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
334 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800335 if (DBG) {
336 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
337 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700338 storeNameAndAddress(null, newAddress);
339 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800340 if (DBG) {
341 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
342 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700343 }
Stanley Tng873b5702017-05-01 21:27:31 -0700344 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
345 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
346 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
347 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800348 final String prevValue =
349 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
350 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700351
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800352 if (DBG) {
353 Slog.d(TAG,
354 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
355 + ", newValue=" + newValue);
356 }
Stanley Tng873b5702017-05-01 21:27:31 -0700357
358 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
359 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800360 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
361 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700362 mHandler.sendMessage(msg);
363 }
364 }
fredc0f420372012-04-12 00:02:00 -0700365 }
366 }
367 };
368
369 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700370 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700371
fredc0f420372012-04-12 00:02:00 -0700372 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700373
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700374 mWirelessConsentRequired = context.getResources()
375 .getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700376
Marie Janssene54b4222017-03-16 18:10:59 -0700377 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700378 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800379 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800380 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700381 mBinding = false;
382 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700383 mEnable = false;
384 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800385 mQuietEnableExternal = false;
386 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700387 mAddress = null;
388 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800389 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700390 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700391 // Observe BLE scan only mode settings change.
392 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700393 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
394 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700395
Stanley Tng61dbd812019-01-13 16:04:31 -0800396 mIsHearingAidProfileSupported = context.getResources()
397 .getBoolean(com.android.internal.R.bool.config_hearing_aid_profile_supported);
398
Stanley Tngfe8c8332018-06-19 08:48:10 -0700399 // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
Stanley Tngfe8c8332018-06-19 08:48:10 -0700400 String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
401 if (!TextUtils.isEmpty(value)) {
Stanley Tng61dbd812019-01-13 16:04:31 -0800402 boolean isHearingAidEnabled = Boolean.parseBoolean(value);
Stanley Tngfe8c8332018-06-19 08:48:10 -0700403 Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
404 FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
Stanley Tng61dbd812019-01-13 16:04:31 -0800405 if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
406 // Overwrite to enable support by FeatureFlag
407 mIsHearingAidProfileSupported = true;
408 }
Stanley Tngfe8c8332018-06-19 08:48:10 -0700409 }
410
Stanley Tng873b5702017-05-01 21:27:31 -0700411 IntentFilter filter = new IntentFilter();
412 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
413 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
414 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700415 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700416 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700417
fredc0f420372012-04-12 00:02:00 -0700418 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800419 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800420 if (DBG) {
421 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
422 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800423 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700424 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200425
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800426 String airplaneModeRadios =
427 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
428 if (airplaneModeRadios == null || airplaneModeRadios.contains(
429 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800430 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800431 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
432 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800433 }
434
Marie Janssen59804562016-12-28 14:13:21 -0800435 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200436 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800437 // Check if device is configured with no home screen, which implies no SystemUI.
438 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
439 if (!noHome) {
440 systemUiUid = mContext.getPackageManager()
441 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
442 UserHandle.USER_SYSTEM);
443 }
444 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200445 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700446 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700447 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200448 }
Marie Janssen59804562016-12-28 14:13:21 -0800449 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700450 }
451
fredc649fe492012-04-19 01:07:18 -0700452 /**
453 * Returns true if airplane mode is currently on
454 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800455 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700456 return Settings.Global.getInt(mContext.getContentResolver(),
457 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700458 }
459
Arthur Hsu2433baf2018-01-11 11:05:11 -0800460 private boolean supportBluetoothPersistedState() {
461 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
462 }
463
fredc649fe492012-04-19 01:07:18 -0700464 /**
465 * Returns true if the Bluetooth saved state is "on"
466 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800467 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800468 if (!supportBluetoothPersistedState()) {
469 return false;
470 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800471 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
472 if (DBG) {
473 Slog.d(TAG, "Bluetooth persisted state: " + state);
474 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700475 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800476 }
477
478 /**
479 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
480 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800481 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800482 if (!supportBluetoothPersistedState()) {
483 return false;
484 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800485 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
486 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700487 }
488
489 /**
490 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700491 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800492 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800493 if (DBG) {
494 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
495 }
Marie Janssenfa630682016-12-15 13:51:30 -0800496 // waive WRITE_SECURE_SETTINGS permission check
497 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800498 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800499 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700500 }
501
502 /**
503 * Returns true if the Bluetooth Adapter's name and address is
504 * locally cached
505 * @return
506 */
fredc0f420372012-04-12 00:02:00 -0700507 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800508 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700509 }
510
fredc649fe492012-04-19 01:07:18 -0700511 /**
512 * Retrieve the Bluetooth Adapter's name and address and save it in
513 * in the local cache
514 */
fredc0f420372012-04-12 00:02:00 -0700515 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800516 if (DBG) {
517 Slog.d(TAG, "Loading stored name and address");
518 }
519 if (mContext.getResources()
520 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
521 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
522 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700523 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800524 if (DBG) {
525 Slog.d(TAG, "invalid bluetooth name and address stored");
526 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700527 return;
528 }
fredc0f420372012-04-12 00:02:00 -0700529 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
530 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800531 if (DBG) {
532 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
533 }
fredc0f420372012-04-12 00:02:00 -0700534 }
535
fredc649fe492012-04-19 01:07:18 -0700536 /**
537 * Save the Bluetooth name and address in the persistent store.
538 * Only non-null values will be saved.
539 * @param name
540 * @param address
541 */
fredc0f420372012-04-12 00:02:00 -0700542 private void storeNameAndAddress(String name, String address) {
543 if (name != null) {
544 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700545 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800546 if (DBG) {
547 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
548 SECURE_SETTINGS_BLUETOOTH_NAME));
549 }
fredc0f420372012-04-12 00:02:00 -0700550 }
551
552 if (address != null) {
553 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800554 mAddress = address;
555 if (DBG) {
556 Slog.d(TAG,
557 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
558 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
559 }
fredc0f420372012-04-12 00:02:00 -0700560 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700561
562 if ((name != null) && (address != null)) {
563 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
564 }
fredc0f420372012-04-12 00:02:00 -0700565 }
566
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800567 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700568 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700569 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700570 return null;
571 }
fredc0f420372012-04-12 00:02:00 -0700572 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
573 msg.obj = callback;
574 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700575
576 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700577 }
578
579 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700580 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700581 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700582 return;
583 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800584 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700585 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
586 msg.obj = callback;
587 mHandler.sendMessage(msg);
588 }
589
590 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800591 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800592 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800593 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
594 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800595 }
fredc0f420372012-04-12 00:02:00 -0700596 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
597 msg.obj = callback;
598 mHandler.sendMessage(msg);
599 }
600
601 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800602 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800603 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800604 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
605 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800606 }
fredc0f420372012-04-12 00:02:00 -0700607 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
608 msg.obj = callback;
609 mHandler.sendMessage(msg);
610 }
611
612 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800613 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
614 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700615 return false;
616 }
617
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700618 try {
619 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800620 if (mBluetooth != null) {
621 return mBluetooth.isEnabled();
622 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700623 } catch (RemoteException e) {
624 Slog.e(TAG, "isEnabled()", e);
625 } finally {
626 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700627 }
628 return false;
629 }
630
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700631 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800632 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800633 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700634 return BluetoothAdapter.STATE_OFF;
635 }
636
637 try {
638 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800639 if (mBluetooth != null) {
640 return mBluetooth.getState();
641 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700642 } catch (RemoteException e) {
643 Slog.e(TAG, "getState()", e);
644 } finally {
645 mBluetoothLock.readLock().unlock();
646 }
647 return BluetoothAdapter.STATE_OFF;
648 }
649
Nitin Arorad055adb2015-03-02 15:03:51 -0800650 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800651 private String mPackageName;
652
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800653 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800654 mPackageName = packageName;
655 }
656
Nitin Arorad055adb2015-03-02 15:03:51 -0800657 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800658 if (DBG) {
659 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800660 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700661
662 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
663 IBinder token = entry.getKey();
664 ClientDeathRecipient deathRec = entry.getValue();
665 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700666 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700667 break;
668 }
669 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800670 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800671
Marie Janssen59804562016-12-28 14:13:21 -0800672 public String getPackageName() {
673 return mPackageName;
674 }
675 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800676
Wei Wang67d84162015-04-26 17:04:29 -0700677 @Override
678 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700679 if (isAirplaneModeOn() && !mEnable) {
680 return false;
681 }
Wei Wang67d84162015-04-26 17:04:29 -0700682 try {
Jack He8caab152018-03-02 13:08:36 -0800683 return Settings.Global.getInt(mContentResolver,
684 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700685 } catch (SettingNotFoundException e) {
686 }
687 return false;
688 }
689
Stanley Tng61dbd812019-01-13 16:04:31 -0800690 @Override
691 public boolean isHearingAidProfileSupported() {
692 return mIsHearingAidProfileSupported;
693 }
694
Wei Wange4a744b2015-06-11 17:50:29 -0700695 // Monitor change of BLE scan only mode settings.
696 private void registerForBleScanModeChange() {
697 ContentObserver contentObserver = new ContentObserver(null) {
698 @Override
699 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800700 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800701 // Nothing to do
702 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800703 }
704 // BLE scan is not available.
705 disableBleScanMode();
706 clearBleApps();
707 try {
708 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800709 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700710 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
711 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800712 mBluetooth.onBrEdrDown();
713 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800714 } catch (RemoteException e) {
715 Slog.e(TAG, "error when disabling bluetooth", e);
716 } finally {
717 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700718 }
719 }
720 };
721
722 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800723 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
724 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700725 }
726
727 // Disable ble scan only mode.
728 private void disableBleScanMode() {
729 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700730 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700731 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800732 if (DBG) {
733 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
734 }
Wei Wange4a744b2015-06-11 17:50:29 -0700735 mEnable = false;
736 }
737 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700738 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700739 } finally {
740 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700741 }
742 }
743
Marie Janssen59804562016-12-28 14:13:21 -0800744 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
745 ClientDeathRecipient r = mBleApps.get(token);
746 if (r == null && enable) {
747 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
748 try {
749 token.linkToDeath(deathRec, 0);
750 } catch (RemoteException ex) {
751 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800752 }
Marie Janssen59804562016-12-28 14:13:21 -0800753 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800754 if (DBG) {
755 Slog.d(TAG, "Registered for death of " + packageName);
756 }
Marie Janssen59804562016-12-28 14:13:21 -0800757 } else if (!enable && r != null) {
758 // Unregister death recipient as the app goes away.
759 token.unlinkToDeath(r, 0);
760 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800761 if (DBG) {
762 Slog.d(TAG, "Unregistered for death of " + packageName);
763 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800764 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800765 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800766 if (DBG) {
767 Slog.d(TAG, appCount + " registered Ble Apps");
768 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800769 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700770 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800771 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800772 if (appCount == 0 && !mEnableExternal) {
773 sendBrEdrDownCallback();
774 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800775 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
777
Wei Wange4a744b2015-06-11 17:50:29 -0700778 // Clear all apps using BLE scan only mode.
779 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800780 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700781 }
782
Marie Janssen59804562016-12-28 14:13:21 -0800783 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800784 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800785 if (DBG) {
786 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
787 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800788 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800789 }
790
791 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700792 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800793 */
Myles Watson304ebf22018-05-11 08:47:24 -0700794 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800795 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700796 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800797 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700798 try {
799 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800800 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700801 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800802 return;
803 }
804 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
805 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800806 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800807 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800808 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700809 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800810 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700811 } finally {
812 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800813 }
814 }
815
816 /**
817 * Inform BluetoothAdapter instances that BREDR part is down
818 * and turn off all service and stack if no LE app needs it
819 */
820 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800821 if (DBG) {
822 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
823 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700824
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700825 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700826 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700827 return;
828 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800829
Martin Brabhamc2b06222017-02-27 16:55:07 -0800830 if (isBleAppPresent()) {
831 // Need to stay at BLE ON. Disconnect all Gatt connections
832 try {
833 mBluetoothGatt.unregAll();
834 } catch (RemoteException e) {
835 Slog.e(TAG, "Unable to disconnect all apps.", e);
836 }
837 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800838 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700839 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800840 if (mBluetooth != null) {
841 mBluetooth.onBrEdrDown();
842 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700843 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700844 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700845 } finally {
846 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800847 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800848 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800849
Nitin Arorad055adb2015-03-02 15:03:51 -0800850 }
851
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800852 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100853 if (isBluetoothDisallowed()) {
854 if (DBG) {
855 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
856 }
857 return false;
858 }
859
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700860 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800861 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700862
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700863 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800864 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
865 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700866 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800867 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
868
869 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700870 throw new SecurityException("no permission to enable Bluetooth quietly");
871 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800872
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800873 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800874 mQuietEnableExternal = true;
875 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800876 sendEnableMsg(true,
877 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800878 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700879 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700880 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700881
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700882 public boolean enable(String packageName) throws RemoteException {
883 final int callingUid = Binder.getCallingUid();
884 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
885
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100886 if (isBluetoothDisallowed()) {
887 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800888 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100889 }
890 return false;
891 }
892
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700893 if (!callerSystem) {
894 if (!checkIfCallerIsForegroundUser()) {
895 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
896 return false;
897 }
898
899 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
900 "Need BLUETOOTH ADMIN permission");
901
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700902 if (!isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800903 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700904 return false;
905 }
fredcf2458862012-04-16 15:18:27 -0700906 }
907
Zhihai Xu401202b2012-12-03 11:36:21 -0800908 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800909 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
910 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700911 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800912
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800913 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800914 mQuietEnableExternal = false;
915 mEnableExternal = true;
916 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800917 sendEnableMsg(false,
918 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800919 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800920 if (DBG) {
921 Slog.d(TAG, "enable returning");
922 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800923 return true;
fredc0f420372012-04-12 00:02:00 -0700924 }
925
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700926 public boolean disable(String packageName, boolean persist) throws RemoteException {
927 final int callingUid = Binder.getCallingUid();
928 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700929
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700930 if (!callerSystem) {
931 if (!checkIfCallerIsForegroundUser()) {
932 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
933 return false;
934 }
935
936 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
937 "Need BLUETOOTH ADMIN permission");
938
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700939 if (isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800940 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700941 return false;
942 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700943 }
944
fredcf2458862012-04-16 15:18:27 -0700945 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800946 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700947 }
fredcf2458862012-04-16 15:18:27 -0700948
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800949 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800950 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800951 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800952 }
953 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800954 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
955 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800956 }
fredc0f420372012-04-12 00:02:00 -0700957 return true;
958 }
959
baishengf62d8692018-01-25 18:07:24 +0800960 private boolean startConsentUiIfNeeded(String packageName,
961 int callingUid, String intentAction) throws RemoteException {
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700962 if (checkBluetoothPermissionWhenWirelessConsentRequired()) {
baishengf62d8692018-01-25 18:07:24 +0800963 return false;
964 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700965 try {
966 // Validate the package only if we are going to use it
967 ApplicationInfo applicationInfo = mContext.getPackageManager()
968 .getApplicationInfoAsUser(packageName,
969 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
970 UserHandle.getUserId(callingUid));
971 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800972 throw new SecurityException("Package " + packageName
973 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700974 }
975
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000976 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000977 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800978 intent.setFlags(
979 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000980 try {
981 mContext.startActivity(intent);
982 } catch (ActivityNotFoundException e) {
983 // Shouldn't happen
984 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
985 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700986 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000987 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700988 } catch (PackageManager.NameNotFoundException e) {
989 throw new RemoteException(e.getMessage());
990 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700991 }
992
baishengf62d8692018-01-25 18:07:24 +0800993 /**
994 * Check if the caller must still pass permission check or if the caller is exempted
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700995 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED check.
baishengf62d8692018-01-25 18:07:24 +0800996 *
997 * Commands from some callers may be exempted from triggering the consent UI when
998 * enabling bluetooth. This exemption is checked via the
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700999 * MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED and allows calls to skip
baishengf62d8692018-01-25 18:07:24 +08001000 * the consent UI where it may otherwise be required.
1001 *
1002 * @hide
1003 */
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001004 private boolean checkBluetoothPermissionWhenWirelessConsentRequired() {
baishengf62d8692018-01-25 18:07:24 +08001005 int result = mContext.checkCallingPermission(
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001006 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED);
baishengf62d8692018-01-25 18:07:24 +08001007 return result == PackageManager.PERMISSION_GRANTED;
1008 }
1009
fredc649fe492012-04-19 01:07:18 -07001010 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -07001011 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001012 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
1013 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -07001014 }
1015
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001016 try {
1017 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001018 if (mUnbinding) {
1019 return;
1020 }
fredc0f420372012-04-12 00:02:00 -07001021 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001022 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001023 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001024 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001025 //Unregister callback object
1026 try {
1027 mBluetooth.unregisterCallback(mBluetoothCallback);
1028 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001029 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001030 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001031 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001032 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001033 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001034 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001035 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001036 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001037 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001038 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001039 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001040 } finally {
1041 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001042 }
1043 }
1044
Matthew Xieddf7e472013-03-01 18:41:02 -08001045 public IBluetoothGatt getBluetoothGatt() {
1046 // sync protection
1047 return mBluetoothGatt;
1048 }
1049
Benjamin Franze8b98922014-11-12 15:57:54 +00001050 @Override
1051 public boolean bindBluetoothProfileService(int bluetoothProfile,
1052 IBluetoothProfileServiceConnection proxy) {
1053 if (!mEnable) {
1054 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001055 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1056 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001057 }
1058 return false;
1059 }
1060 synchronized (mProfileServices) {
1061 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1062 if (psc == null) {
1063 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001064 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1065 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001066 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001067
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001068 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1069 return false;
1070 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001071
1072 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001073 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001074 if (!psc.bindService()) {
1075 return false;
1076 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001077
Benjamin Franze8b98922014-11-12 15:57:54 +00001078 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001079 }
1080 }
1081
1082 // Introducing a delay to give the client app time to prepare
1083 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1084 addProxyMsg.arg1 = bluetoothProfile;
1085 addProxyMsg.obj = proxy;
1086 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1087 return true;
1088 }
1089
1090 @Override
1091 public void unbindBluetoothProfileService(int bluetoothProfile,
1092 IBluetoothProfileServiceConnection proxy) {
1093 synchronized (mProfileServices) {
1094 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1095 if (psc == null) {
1096 return;
1097 }
1098 psc.removeProxy(proxy);
1099 }
1100 }
1101
1102 private void unbindAllBluetoothProfileServices() {
1103 synchronized (mProfileServices) {
1104 for (Integer i : mProfileServices.keySet()) {
1105 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001106 try {
1107 mContext.unbindService(psc);
1108 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001109 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001110 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001111 psc.removeAllProxies();
1112 }
1113 mProfileServices.clear();
1114 }
1115 }
1116
1117 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001118 * Send enable message and set adapter name and address. Called when the boot phase becomes
1119 * PHASE_SYSTEM_SERVICES_READY.
1120 */
1121 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001122 if (DBG) {
1123 Slog.d(TAG, "Bluetooth boot completed");
1124 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001125 UserManagerInternal userManagerInternal =
1126 LocalServices.getService(UserManagerInternal.class);
1127 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001128 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001129 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001130 return;
1131 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001132 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001133 if (DBG) {
1134 Slog.d(TAG, "Auto-enabling Bluetooth.");
1135 }
Jack He8caab152018-03-02 13:08:36 -08001136 sendEnableMsg(mQuietEnableExternal,
1137 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1138 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001139 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001140 if (DBG) {
1141 Slog.d(TAG, "Getting adapter name and address");
1142 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001143 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1144 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001145 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001146 }
1147
1148 /**
1149 * Called when switching to a different foreground user.
1150 */
1151 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001152 if (DBG) {
1153 Slog.d(TAG, "User " + userHandle + " switched");
1154 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001155 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1156 }
1157
1158 /**
1159 * Called when user is unlocked.
1160 */
1161 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001162 if (DBG) {
1163 Slog.d(TAG, "User " + userHandle + " unlocked");
1164 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001165 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001166 }
1167
1168 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001169 * This class manages the clients connected to a given ProfileService
1170 * and maintains the connection with that service.
1171 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001172 private final class ProfileServiceConnections
1173 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001174 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001175 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001176 IBinder mService;
1177 ComponentName mClassName;
1178 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001179 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001180
1181 ProfileServiceConnections(Intent intent) {
1182 mService = null;
1183 mClassName = null;
1184 mIntent = intent;
1185 }
1186
Benjamin Franz5b614592014-12-09 18:58:45 +00001187 private boolean bindService() {
jonerlin37fc85d2018-08-09 16:39:43 +08001188 int state = BluetoothAdapter.STATE_OFF;
1189 try {
1190 mBluetoothLock.readLock().lock();
1191 if (mBluetooth != null) {
1192 state = mBluetooth.getState();
1193 }
1194 } catch (RemoteException e) {
1195 Slog.e(TAG, "Unable to call getState", e);
1196 return false;
1197 } finally {
1198 mBluetoothLock.readLock().unlock();
1199 }
1200
1201 if (!mEnable || state != BluetoothAdapter.STATE_ON) {
1202 if (DBG) {
1203 Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
1204 }
1205 return false;
1206 }
1207
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001208 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1209 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001210 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1211 msg.obj = this;
1212 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001213 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001214 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001215 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001216 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001217 }
1218
1219 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1220 mProxies.register(proxy);
1221 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001222 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001223 proxy.onServiceConnected(mClassName, mService);
1224 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001225 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001226 }
1227 } else {
1228 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1229 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1230 msg.obj = this;
1231 mHandler.sendMessage(msg);
1232 }
1233 }
1234 }
1235
1236 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1237 if (proxy != null) {
1238 if (mProxies.unregister(proxy)) {
1239 try {
1240 proxy.onServiceDisconnected(mClassName);
1241 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001242 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001243 }
1244 }
1245 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001246 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001247 }
1248 }
1249
1250 private void removeAllProxies() {
1251 onServiceDisconnected(mClassName);
1252 mProxies.kill();
1253 }
1254
1255 @Override
1256 public void onServiceConnected(ComponentName className, IBinder service) {
1257 // remove timeout message
1258 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1259 mService = service;
1260 mClassName = className;
1261 try {
1262 mService.linkToDeath(this, 0);
1263 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001264 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001265 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001266
1267 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001268 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001269 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001270 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001271 mInvokingProxyCallbacks = true;
1272
1273 final int n = mProxies.beginBroadcast();
1274 try {
1275 for (int i = 0; i < n; i++) {
1276 try {
1277 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1278 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001279 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001280 }
1281 }
1282 } finally {
1283 mProxies.finishBroadcast();
1284 mInvokingProxyCallbacks = false;
1285 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001286 }
1287
1288 @Override
1289 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001290 if (mService == null) {
1291 return;
1292 }
Chienyuan177156b2018-12-18 10:40:25 +08001293 try {
1294 mService.unlinkToDeath(this, 0);
1295 } catch (NoSuchElementException e) {
1296 Log.e(TAG, "error unlinking to death", e);
1297 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001298 mService = null;
1299 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001300
1301 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001302 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001303 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001304 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001305 mInvokingProxyCallbacks = true;
1306
1307 final int n = mProxies.beginBroadcast();
1308 try {
1309 for (int i = 0; i < n; i++) {
1310 try {
1311 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1312 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001313 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001314 }
1315 }
1316 } finally {
1317 mProxies.finishBroadcast();
1318 mInvokingProxyCallbacks = false;
1319 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001320 }
1321
1322 @Override
1323 public void binderDied() {
1324 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001325 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001326 }
1327 onServiceDisconnected(mClassName);
1328 // Trigger rebind
1329 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1330 msg.obj = this;
1331 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1332 }
1333 }
1334
fredcbf072a72012-05-09 16:52:50 -07001335 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001336 try {
1337 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001338 if (DBG) {
1339 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1340 + " receivers.");
1341 }
1342 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001343 try {
1344 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1345 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001346 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001347 }
fredcbf072a72012-05-09 16:52:50 -07001348 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001349 } finally {
1350 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001351 }
fredcbf072a72012-05-09 16:52:50 -07001352 }
1353
1354 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001355 * Inform BluetoothAdapter instances that Adapter service is up
1356 */
1357 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001358 try {
1359 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001360 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1361 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001362 try {
1363 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001364 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001365 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001366 }
1367 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001368 } finally {
1369 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001370 }
1371 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001372
Zhihai Xu40874a02012-10-08 17:57:03 -07001373 /**
fredcbf072a72012-05-09 16:52:50 -07001374 * Inform BluetoothAdapter instances that Adapter service is down
1375 */
1376 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001377 try {
1378 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001379 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1380 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001381 try {
1382 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001383 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001384 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001385 }
1386 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001387 } finally {
1388 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001389 }
1390 }
Svet Ganov408abf72015-05-12 19:13:36 -07001391
fredc0f420372012-04-12 00:02:00 -07001392 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001393 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001394
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001395 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1396 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001397 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001398 }
1399
Svet Ganov408abf72015-05-12 19:13:36 -07001400 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1401 != PackageManager.PERMISSION_GRANTED) {
1402 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1403 }
1404
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001405 try {
1406 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001407 if (mBluetooth != null) {
1408 return mBluetooth.getAddress();
1409 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001410 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001411 Slog.e(TAG,
1412 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1413 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001414 } finally {
1415 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001416 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001417
Matthew Xiecdce0b92012-07-12 19:06:15 -07001418 // mAddress is accessed from outside.
1419 // It is alright without a lock. Here, bluetooth is off, no other thread is
1420 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001421 return mAddress;
1422 }
fredc649fe492012-04-19 01:07:18 -07001423
fredc0f420372012-04-12 00:02:00 -07001424 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001425 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001426
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001427 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1428 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001429 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001430 }
1431
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001432 try {
1433 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001434 if (mBluetooth != null) {
1435 return mBluetooth.getName();
1436 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001437 } catch (RemoteException e) {
1438 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1439 } finally {
1440 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001441 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001442
Matthew Xiecdce0b92012-07-12 19:06:15 -07001443 // mName is accessed from outside.
1444 // It alright without a lock. Here, bluetooth is off, no other thread is
1445 // changing mName
fredc0f420372012-04-12 00:02:00 -07001446 return mName;
1447 }
1448
fredc0f420372012-04-12 00:02:00 -07001449 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001450 public void onServiceConnected(ComponentName componentName, IBinder service) {
1451 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001452 if (DBG) {
1453 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1454 }
fredc0f420372012-04-12 00:02:00 -07001455 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001456 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001457 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001458 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001459 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1460 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001461 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001462 return;
1463 }
fredc0f420372012-04-12 00:02:00 -07001464 msg.obj = service;
1465 mHandler.sendMessage(msg);
1466 }
1467
Marie Janssencb21ad72016-12-13 10:51:02 -08001468 public void onServiceDisconnected(ComponentName componentName) {
1469 // Called if we unexpectedly disconnect.
1470 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001471 if (DBG) {
1472 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1473 }
fredc0f420372012-04-12 00:02:00 -07001474 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001475 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001476 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001477 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001478 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1479 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001480 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001481 return;
1482 }
fredc0f420372012-04-12 00:02:00 -07001483 mHandler.sendMessage(msg);
1484 }
1485 }
1486
1487 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1488
Zhihai Xu40874a02012-10-08 17:57:03 -07001489 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001490 boolean mGetNameAddressOnly = false;
1491
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001492 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001493 super(looper);
1494 }
1495
fredc0f420372012-04-12 00:02:00 -07001496 @Override
1497 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001498 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001499 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001500 if (DBG) {
1501 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1502 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001503 try {
1504 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001505 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001506 if (DBG) {
1507 Slog.d(TAG, "Binding to service to get name and address");
1508 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001509 mGetNameAddressOnly = true;
1510 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1511 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1512 Intent i = new Intent(IBluetooth.class.getName());
1513 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001514 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1515 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001516 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1517 } else {
1518 mBinding = true;
1519 }
1520 } else if (mBluetooth != null) {
1521 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001522 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001523 } catch (RemoteException re) {
1524 Slog.e(TAG, "Unable to grab names", re);
1525 }
1526 if (mGetNameAddressOnly && !mEnable) {
1527 unbindAndFinish();
1528 }
1529 mGetNameAddressOnly = false;
1530 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001531 } finally {
1532 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001533 }
1534 break;
1535
Matthew Xiecdce0b92012-07-12 19:06:15 -07001536 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001537 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001538 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001539 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001540 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1541 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001542
1543 // Use service interface to get the exact state
1544 try {
1545 mBluetoothLock.readLock().lock();
1546 if (mBluetooth != null) {
1547 int state = mBluetooth.getState();
1548 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001549 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001550 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001551 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001552 break;
1553 }
1554 }
1555 } catch (RemoteException e) {
1556 Slog.e(TAG, "", e);
1557 } finally {
1558 mBluetoothLock.readLock().unlock();
1559 }
1560
1561 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001562 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001563 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001564 } else {
1565 //
1566 // We need to wait until transitioned to STATE_OFF and
1567 // the previous Bluetooth process has exited. The
1568 // waiting period has three components:
1569 // (a) Wait until the local state is STATE_OFF. This
1570 // is accomplished by "waitForOnOff(false, true)".
1571 // (b) Wait until the STATE_OFF state is updated to
1572 // all components.
1573 // (c) Wait until the Bluetooth process exits, and
1574 // ActivityManager detects it.
1575 // The waiting for (b) and (c) is accomplished by
1576 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1577 // message. On slower devices, that delay needs to be
1578 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1579 //
1580 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001581 Message restartMsg =
1582 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1583 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001584 }
fredc649fe492012-04-19 01:07:18 -07001585 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001586
fredc0f420372012-04-12 00:02:00 -07001587 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001588 if (DBG) {
1589 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1590 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001591 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1592 if (mEnable && mBluetooth != null) {
1593 waitForOnOff(true, false);
1594 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001595 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001596 waitForOnOff(false, false);
1597 } else {
1598 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001599 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001600 }
fredc0f420372012-04-12 00:02:00 -07001601 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001602
Stanley Tng873b5702017-05-01 21:27:31 -07001603 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001604 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1605 if (DBG) {
1606 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001607 }
Jack He8caab152018-03-02 13:08:36 -08001608 persistBluetoothSetting(BLUETOOTH_OFF);
1609 mEnableExternal = false;
1610 sendDisableMsg(
1611 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1612 mContext.getPackageName());
1613 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1614 if (DBG) {
1615 Slog.d(TAG, "Restore Bluetooth state to enabled");
1616 }
1617 mQuietEnableExternal = false;
1618 mEnableExternal = true;
1619 // waive WRITE_SECURE_SETTINGS permission check
1620 sendEnableMsg(false,
1621 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1622 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001623 }
1624 break;
1625
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001626 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001627 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001628 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001629 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001630 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001631 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001632 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001633 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001634 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001635 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001636 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1637 IBluetoothStateChangeCallback callback =
1638 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001639 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001640 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001641 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001642 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1643 IBluetoothStateChangeCallback callback =
1644 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001645 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001646 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001647 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001648 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001649 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001650 if (psc == null) {
1651 break;
1652 }
1653 IBluetoothProfileServiceConnection proxy =
1654 (IBluetoothProfileServiceConnection) msg.obj;
1655 psc.addProxy(proxy);
1656 break;
1657 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001658 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001659 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1660 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1661 if (psc == null) {
1662 break;
1663 }
1664 psc.bindService();
1665 break;
1666 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001667 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1668 if (DBG) {
1669 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1670 }
fredc0f420372012-04-12 00:02:00 -07001671
1672 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001673 try {
1674 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001675 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001676 mBluetoothGatt =
1677 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001678 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001679 break;
1680 } // else must be SERVICE_IBLUETOOTH
1681
1682 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001683 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001684
fredc0f420372012-04-12 00:02:00 -07001685 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001686 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001687 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001688
Ajay Panicker4bb48302016-03-31 14:14:27 -07001689 if (!isNameAndAddressSet()) {
1690 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1691 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001692 if (mGetNameAddressOnly) {
1693 return;
1694 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001695 }
1696
Matthew Xiecdce0b92012-07-12 19:06:15 -07001697 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001698 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001699 mBluetooth.registerCallback(mBluetoothCallback);
1700 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001701 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001702 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001703 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001704 sendBluetoothServiceUpCallback();
1705
Matthew Xiecdce0b92012-07-12 19:06:15 -07001706 //Do enable request
1707 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001708 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001709 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001710 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001711 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001712 } else {
1713 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001714 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001715 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001716 }
1717 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001718 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001719 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001720 } finally {
1721 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001722 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001723
1724 if (!mEnable) {
1725 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001726 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001727 waitForOnOff(false, false);
1728 }
fredc649fe492012-04-19 01:07:18 -07001729 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001730 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001731 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001732 int prevState = msg.arg1;
1733 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001734 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001735 Slog.d(TAG,
1736 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1737 prevState) + " > " + BluetoothAdapter.nameForState(
1738 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001739 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001740 mState = newState;
1741 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001742 // handle error state transition case from TURNING_ON to OFF
1743 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001744 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1745 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001746 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001747 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001748 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1749 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001750 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001751 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001752 // If we tried to enable BT while BT was in the process of shutting down,
1753 // wait for the BT process to fully tear down and then force a restart
1754 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001755 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1756 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001757 if (mEnable) {
1758 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1759 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001760 Message restartMsg =
1761 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001762 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1763 }
1764 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001765 if (newState == BluetoothAdapter.STATE_ON
1766 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001767 // bluetooth is working, reset the counter
1768 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001769 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001770 mErrorRecoveryRetryCounter = 0;
1771 }
1772 }
fredc649fe492012-04-19 01:07:18 -07001773 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001774 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001775 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001776 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001777 try {
1778 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001779 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1780 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001781 if (mBluetooth == null) {
1782 break;
1783 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001784 mBluetooth = null;
1785 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1786 mBluetoothGatt = null;
1787 break;
1788 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001789 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001790 break;
1791 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001792 } finally {
1793 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301794 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001795
Marie Janssene54b4222017-03-16 18:10:59 -07001796 // log the unexpected crash
1797 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001798 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1799 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001800 if (mEnable) {
1801 mEnable = false;
1802 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001803 Message restartMsg =
1804 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1805 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001806 }
1807
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001808 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001809
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001810 // Send BT state broadcast to update
1811 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001812 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1813 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001814 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001815 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001816 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001817 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001818 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1819 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001820 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001821 }
1822
1823 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1824 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001825 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001826 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001827 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001828 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301829 /* Enable without persisting the setting as
1830 it doesnt change when IBluetooth
1831 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001832 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001833 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1834 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001835 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301836 break;
1837 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001838 case MESSAGE_TIMEOUT_BIND: {
1839 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1840 mBluetoothLock.writeLock().lock();
1841 mBinding = false;
1842 mBluetoothLock.writeLock().unlock();
1843 break;
1844 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001845 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001846 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001847 mBluetoothLock.writeLock().lock();
1848 mUnbinding = false;
1849 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001850 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001851 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001852
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001853 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001854 if (DBG) {
1855 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1856 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001857 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001858
Zhihai Xu40874a02012-10-08 17:57:03 -07001859 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001860 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001861 try {
1862 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001863 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001864 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001865 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001866 } catch (RemoteException re) {
1867 Slog.e(TAG, "Unable to unregister", re);
1868 } finally {
1869 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001870 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001871
1872 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1873 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1874 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1875 mState = BluetoothAdapter.STATE_OFF;
1876 }
1877 if (mState == BluetoothAdapter.STATE_OFF) {
1878 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1879 mState = BluetoothAdapter.STATE_TURNING_ON;
1880 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001881
1882 waitForOnOff(true, false);
1883
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001884 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1885 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1886 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001887
Benjamin Franze8b98922014-11-12 15:57:54 +00001888 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001889 // disable
Jack He8caab152018-03-02 13:08:36 -08001890 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1891 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001892 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001893 // Pbap service need receive STATE_TURNING_OFF intent to close
1894 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001895 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001896
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001897 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001898
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001899 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001900 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001901 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001902
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001903 try {
1904 mBluetoothLock.writeLock().lock();
1905 if (mBluetooth != null) {
1906 mBluetooth = null;
1907 // Unbind
1908 mContext.unbindService(mConnection);
1909 }
1910 mBluetoothGatt = null;
1911 } finally {
1912 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001913 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001914
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001915 //
1916 // If disabling Bluetooth times out, wait for an
1917 // additional amount of time to ensure the process is
1918 // shut down completely before attempting to restart.
1919 //
1920 if (didDisableTimeout) {
1921 SystemClock.sleep(3000);
1922 } else {
1923 SystemClock.sleep(100);
1924 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001925
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001926 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1927 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001928 // enable
Jack He8caab152018-03-02 13:08:36 -08001929 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1930 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001931 // mEnable flag could have been reset on disableBLE. Reenable it.
1932 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001933 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001934 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001935 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1936 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001937 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001938 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1939 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001940 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001941 }
John Spurlock8a985d22014-02-25 09:40:05 -05001942 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001943 break;
1944 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001945 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001946 if (DBG) {
1947 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1948 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001949 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1950
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001951 if (mEnable && !mBinding && (mBluetooth == null)) {
1952 // We should be connected, but we gave up for some
1953 // reason; maybe the Bluetooth service wasn't encryption
1954 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001955 if (DBG) {
1956 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1957 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001958 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001959 }
1960 }
fredc0f420372012-04-12 00:02:00 -07001961 }
1962 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001963 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001964
Zhihai Xu401202b2012-12-03 11:36:21 -08001965 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001966 mQuietEnable = quietMode;
1967
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001968 try {
1969 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001970 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001971 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001972 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1973 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001974 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001975 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001976 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001977 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001978 } else {
1979 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001980 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001981 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001982 //Enable bluetooth
1983 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001984 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001985 if (!mBluetooth.enable()) {
1986 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001987 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001988 } else {
1989 if (!mBluetooth.enableNoAutoConnect()) {
1990 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001991 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001992 }
1993 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001994 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001995 }
1996 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001997 } finally {
1998 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001999 }
2000 }
2001
Dianne Hackborn221ea892013-08-04 16:50:16 -07002002 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
2003 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
2004 intent.setComponent(comp);
2005 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07002006 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07002007 return false;
2008 }
2009 return true;
2010 }
2011
Zhihai Xu401202b2012-12-03 11:36:21 -08002012 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002013 try {
2014 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08002015 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002016 if (DBG) {
2017 Slog.d(TAG, "Sending off request.");
2018 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002019 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002020 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002021 }
2022 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002023 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002024 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002025 } finally {
2026 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002027 }
2028 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002029
2030 private boolean checkIfCallerIsForegroundUser() {
2031 int foregroundUser;
2032 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002033 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07002034 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00002035 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
2036 UserInfo ui = um.getProfileParent(callingUser);
2037 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002038 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07002039 boolean valid = false;
2040 try {
2041 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002042 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2043 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002044 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002045 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2046 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2047 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002048 }
2049 } finally {
2050 Binder.restoreCallingIdentity(callingIdentity);
2051 }
2052 return valid;
2053 }
2054
Nitin Arorad055adb2015-03-02 15:03:51 -08002055 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002056 if (DBG) {
2057 Slog.d(TAG,
2058 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2059 + BluetoothAdapter.nameForState(newState));
2060 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002061 // Send broadcast message to everyone else
2062 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2063 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2064 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2065 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2066 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2067 }
2068
Zhihai Xu40874a02012-10-08 17:57:03 -07002069 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002070 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002071 if (prevState == newState) { // No change. Nothing to do.
2072 return;
2073 }
2074 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002075 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002076 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002077 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002078
Marie Janssencb21ad72016-12-13 10:51:02 -08002079 if (newState == BluetoothAdapter.STATE_OFF) {
2080 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002081 if (DBG) {
2082 Slog.d(TAG, "Bluetooth is complete send Service Down");
2083 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002084 sendBluetoothServiceDownCallback();
2085 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002086 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002087 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002088 isStandardBroadcast = false;
2089
Marie Janssencb21ad72016-12-13 10:51:02 -08002090 } else if (!intermediate_off) {
2091 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002092 if (DBG) {
2093 Slog.d(TAG, "Bluetooth is in LE only mode");
2094 }
Myles Watson304ebf22018-05-11 08:47:24 -07002095 if (mBluetoothGatt != null || !mContext.getPackageManager()
2096 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2097 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002098 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002099 if (DBG) {
2100 Slog.d(TAG, "Binding Bluetooth GATT service");
2101 }
Myles Watson304ebf22018-05-11 08:47:24 -07002102 Intent i = new Intent(IBluetoothGatt.class.getName());
2103 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2104 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002105 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002106 sendBleStateChanged(prevState, newState);
2107 //Don't broadcase this as std intent
2108 isStandardBroadcast = false;
2109
2110 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002111 if (DBG) {
2112 Slog.d(TAG, "Intermediate off, back to LE only mode");
2113 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002114 // For LE only mode, broadcast as is
2115 sendBleStateChanged(prevState, newState);
2116 sendBluetoothStateCallback(false); // BT is OFF for general users
2117 // Broadcast as STATE_OFF
2118 newState = BluetoothAdapter.STATE_OFF;
2119 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002120 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002121 } else if (newState == BluetoothAdapter.STATE_ON) {
2122 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2123 sendBluetoothStateCallback(isUp);
2124 sendBleStateChanged(prevState, newState);
2125
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002126 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2127 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002128 sendBleStateChanged(prevState, newState);
2129 isStandardBroadcast = false;
2130
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002131 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2132 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002133 sendBleStateChanged(prevState, newState);
2134 }
2135
2136 if (isStandardBroadcast) {
2137 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2138 // Show prevState of BLE_ON as OFF to standard users
2139 prevState = BluetoothAdapter.STATE_OFF;
2140 }
2141 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2142 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2143 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2144 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2145 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002146 }
2147 }
2148
2149 /**
2150 * if on is true, wait for state become ON
2151 * if off is true, wait for state become OFF
2152 * if both on and off are false, wait for state not ON
2153 */
2154 private boolean waitForOnOff(boolean on, boolean off) {
2155 int i = 0;
2156 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002157 try {
2158 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002159 if (mBluetooth == null) {
2160 break;
2161 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002162 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002163 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2164 return true;
2165 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002166 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002167 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2168 return true;
2169 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002170 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002171 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2172 return true;
2173 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002174 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002175 } catch (RemoteException e) {
2176 Slog.e(TAG, "getState()", e);
2177 break;
2178 } finally {
2179 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002180 }
2181 if (on || off) {
2182 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002183 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002184 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002185 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002186 i++;
2187 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002188 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002189 return false;
2190 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002191
Jack He8caab152018-03-02 13:08:36 -08002192 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002193 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002194 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002195 }
2196
Jack He8caab152018-03-02 13:08:36 -08002197 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002198 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002199 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002200 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002201 }
2202
Jack He8caab152018-03-02 13:08:36 -08002203 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002204 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002205 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002206 mActiveLogs.remove();
2207 }
Jack He8caab152018-03-02 13:08:36 -08002208 mActiveLogs.add(
2209 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002210 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002211
2212 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2213 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2214 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2215 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002216 }
2217
Marie Janssene54b4222017-03-16 18:10:59 -07002218 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002219 synchronized (mCrashTimestamps) {
2220 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2221 mCrashTimestamps.removeFirst();
2222 }
2223 mCrashTimestamps.add(System.currentTimeMillis());
2224 mCrashes++;
2225 }
Marie Janssene54b4222017-03-16 18:10:59 -07002226 }
2227
Marie Janssen2977c3e2016-11-09 12:01:24 -08002228 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002229 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002230 try {
2231 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002232 if (mBluetooth != null) {
2233 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002234 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002235 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002236 } catch (RemoteException re) {
2237 Slog.e(TAG, "Unable to unregister", re);
2238 } finally {
2239 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002240 }
2241
2242 SystemClock.sleep(500);
2243
2244 // disable
Jack He8caab152018-03-02 13:08:36 -08002245 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2246 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002247 handleDisable();
2248
2249 waitForOnOff(false, true);
2250
2251 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002252
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002253 try {
2254 mBluetoothLock.writeLock().lock();
2255 if (mBluetooth != null) {
2256 mBluetooth = null;
2257 // Unbind
2258 mContext.unbindService(mConnection);
2259 }
2260 mBluetoothGatt = null;
2261 } finally {
2262 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002263 }
2264
2265 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2266 mState = BluetoothAdapter.STATE_OFF;
2267
Marie Janssen2977c3e2016-11-09 12:01:24 -08002268 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002269 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002270 }
2271
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002272 mEnable = false;
2273
2274 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2275 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002276 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002277 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2278 } else {
2279 // todo: notify user to power down and power up phone to make bluetooth work.
2280 }
2281 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002282
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002283 private boolean isBluetoothDisallowed() {
2284 long callingIdentity = Binder.clearCallingIdentity();
2285 try {
2286 return mContext.getSystemService(UserManager.class)
2287 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2288 } finally {
2289 Binder.restoreCallingIdentity(callingIdentity);
2290 }
2291 }
2292
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002293 /**
2294 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002295 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2296 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002297 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002298 * @param userId user to disable bluetooth sharing for.
2299 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002300 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002301 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002302 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2303 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002304 final int newState =
2305 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2306 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002307 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002308 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002309 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2310 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002311 } catch (Exception e) {
2312 // The component was not found, do nothing.
2313 }
2314 }
2315
Mike Lockwood726d4de2014-10-28 14:06:28 -07002316 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002317 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002318 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2319 return;
2320 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002321 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002322
2323 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2324
2325 if (!protoOut) {
2326 writer.println("Bluetooth Status");
2327 writer.println(" enabled: " + isEnabled());
2328 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2329 writer.println(" address: " + mAddress);
2330 writer.println(" name: " + mName);
2331 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002332 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002333 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2334 (int) (onDuration / (1000 * 60 * 60)),
2335 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2336 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002337 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002338 }
2339
Marie Janssena95924d2017-01-18 09:37:52 -08002340 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002341 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002342 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002343 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002344 for (ActiveLog log : mActiveLogs) {
2345 writer.println(" " + log);
2346 }
Marie Janssen59804562016-12-28 14:13:21 -08002347 }
2348
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002349 writer.println(
2350 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2351 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2352 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2353 }
Marie Janssene54b4222017-03-16 18:10:59 -07002354 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002355 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002356 }
2357
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002358 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2359 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002360 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002361 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002362 }
2363
Marie Janssena95924d2017-01-18 09:37:52 -08002364 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002365 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002366 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002367 // Add arg to produce output
2368 args = new String[1];
2369 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002370 }
Marie Janssen59804562016-12-28 14:13:21 -08002371 }
2372
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002373 if (mBluetoothBinder == null) {
2374 errorMsg = "Bluetooth Service not connected";
2375 } else {
2376 try {
2377 mBluetoothBinder.dump(fd, args);
2378 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002379 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002380 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002381 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002382 if (errorMsg != null) {
2383 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002384 if (protoOut) {
2385 return;
2386 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002387 writer.println(errorMsg);
2388 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002389 }
Jack He8caab152018-03-02 13:08:36 -08002390
2391 private static String getEnableDisableReasonString(int reason) {
2392 switch (reason) {
2393 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2394 return "APPLICATION_REQUEST";
2395 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2396 return "AIRPLANE_MODE";
2397 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2398 return "DISALLOWED";
2399 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2400 return "RESTARTED";
2401 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2402 return "START_ERROR";
2403 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2404 return "SYSTEM_BOOT";
2405 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2406 return "CRASH";
2407 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2408 return "USER_SWITCH";
2409 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2410 return "RESTORE_USER_SETTING";
2411 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2412 default: return "UNKNOWN[" + reason + "]";
2413 }
2414 }
fredc0f420372012-04-12 00:02:00 -07002415}