blob: fa8eda54e53cb2f8e33e2e0327df37699158a406 [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;
Jack Hea80cead2019-04-23 20:00:18 -070022import android.app.AppOpsManager;
fredc0f420372012-04-12 00:02:00 -070023import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000024import android.bluetooth.BluetoothProfile;
Jack He8caab152018-03-02 13:08:36 -080025import android.bluetooth.BluetoothProtoEnums;
fredc0f420372012-04-12 00:02:00 -070026import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070027import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070028import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000029import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070030import android.bluetooth.IBluetoothManager;
31import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000032import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070033import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070034import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070035import android.content.BroadcastReceiver;
36import android.content.ComponentName;
37import android.content.ContentResolver;
38import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
41import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070042import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010043import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070044import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000045import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070046import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070047import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010048import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070049import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070050import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070051import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070052import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070053import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070054import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070055import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070056import android.os.SystemClock;
Stanley Tngfe8c8332018-06-19 08:48:10 -070057import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070058import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000059import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010060import android.os.UserManagerInternal;
61import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070062import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070063import android.provider.Settings.SettingNotFoundException;
Stanley Tngfe8c8332018-06-19 08:48:10 -070064import android.text.TextUtils;
65import android.util.FeatureFlagUtils;
66import android.util.Log;
Jeff Sharkey67609c72016-03-05 14:29:13 -070067import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000068import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070069
Arthur Hsuf3f95a92018-01-11 16:46:22 -080070import com.android.internal.R;
Ugo Yufd8efab2019-10-16 20:27:23 +080071import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060072import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010073import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010074
Mike Lockwood726d4de2014-10-28 14:06:28 -070075import java.io.FileDescriptor;
76import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000077import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080078import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080079import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000080import java.util.Map;
Chienyuan177156b2018-12-18 10:40:25 +080081import java.util.NoSuchElementException;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010082import java.util.concurrent.ConcurrentHashMap;
83import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070084
Marie Janssen59804562016-12-28 14:13:21 -080085
fredc0f420372012-04-12 00:02:00 -070086class BluetoothManagerService extends IBluetoothManager.Stub {
87 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070088 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070089
fredc0f420372012-04-12 00:02:00 -070090 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
91 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070092
Myles Watsonb5cd11a2017-11-27 16:42:11 -080093 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
94 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
95 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070096
97 private static final int ACTIVE_LOG_MAX_SIZE = 20;
98 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070099
fredc0f420372012-04-12 00:02:00 -0700100 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530101 //Maximum msec to wait for service restart
Ugo Yu1ff6fd32019-11-20 17:59:11 +0800102 private static final int SERVICE_RESTART_TIME_MS = 400;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800103 //Maximum msec to wait for restart due to error
104 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700105 //Maximum msec to delay MESSAGE_USER_SWITCHED
106 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000107 // Delay for the addProxy function in msec
108 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700109
110 private static final int MESSAGE_ENABLE = 1;
111 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700112 private static final int MESSAGE_REGISTER_ADAPTER = 20;
113 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
114 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
115 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
116 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
117 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530118 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700119 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
120 private static final int MESSAGE_TIMEOUT_BIND = 100;
121 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700122 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700123 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700124 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000125 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
126 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700127 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
128
129 private static final int RESTORE_SETTING_TO_ON = 1;
130 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800131
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700132 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800133
Zhihai Xu401202b2012-12-03 11:36:21 -0800134 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800135 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800136 // Bluetooth persisted setting is on
137 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800138 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800139 // Bluetooth persisted setting is on
140 // but Airplane mode will affect Bluetooth state at start up
141 // and Airplane mode will have higher priority.
Ugo Yufd8efab2019-10-16 20:27:23 +0800142 @VisibleForTesting
143 static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700144
Matthew Xieddf7e472013-03-01 18:41:02 -0800145 private static final int SERVICE_IBLUETOOTH = 1;
146 private static final int SERVICE_IBLUETOOTHGATT = 2;
147
fredc0f420372012-04-12 00:02:00 -0700148 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700149
150 // Locks are not provided for mName and mAddress.
151 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700152 private String mAddress;
153 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700154 private final ContentResolver mContentResolver;
155 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
156 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800157 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700158 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800159 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800160 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700161 private boolean mBinding;
162 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800163
Ugo Yufd8efab2019-10-16 20:27:23 +0800164 private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
165
Zhihai Xu401202b2012-12-03 11:36:21 -0800166 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700167 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800168 private boolean mEnable;
169
Jack He8caab152018-03-02 13:08:36 -0800170 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700171 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
172 }
173
Marie Janssen59804562016-12-28 14:13:21 -0800174 /**
175 * Used for tracking apps that enabled / disabled Bluetooth.
176 */
177 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800178 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800179 private String mPackageName;
180 private boolean mEnable;
181 private long mTimestamp;
182
Jack He8caab152018-03-02 13:08:36 -0800183 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
184 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800185 mPackageName = packageName;
186 mEnable = enable;
187 mTimestamp = timestamp;
188 }
189
Marie Janssen59804562016-12-28 14:13:21 -0800190 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800191 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
192 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800193 }
194
195 }
196
Jack He8caab152018-03-02 13:08:36 -0800197 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
198 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700199 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700200 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800201
202 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800203 // synchronize with broadcast receiver.
204 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800205 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800206
207 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800208 private Map<IBinder, ClientDeathRecipient> mBleApps =
209 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800210
Zhihai Xu40874a02012-10-08 17:57:03 -0700211 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700212 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800213 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200214 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700215
Stanley Tng61dbd812019-01-13 16:04:31 -0800216 private boolean mIsHearingAidProfileSupported;
217
Jack Hea80cead2019-04-23 20:00:18 -0700218 private AppOpsManager mAppOps;
219
Benjamin Franze8b98922014-11-12 15:57:54 +0000220 // Save a ProfileServiceConnections object for each of the bound
221 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800222 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000223
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700224 private final boolean mWirelessConsentRequired;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700225
Marie Janssen59804562016-12-28 14:13:21 -0800226 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700227 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800228 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
229 Message msg =
230 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700231 mHandler.sendMessage(msg);
232 }
233 };
234
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100235 private final UserRestrictionsListener mUserRestrictionsListener =
236 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800237 @Override
238 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
239 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700240
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800241 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
242 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
243 updateOppLauncherComponentState(userId,
244 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
245 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100246
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800247 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
248 if (userId == UserHandle.USER_SYSTEM
249 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
250 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
251 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
252 UserManager.DISALLOW_BLUETOOTH)) {
253 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800254 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
255 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800256 } else {
257 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
258 UserManager.DISALLOW_BLUETOOTH_SHARING));
259 }
260 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100261 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800262 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100263
Ugo Yufd8efab2019-10-16 20:27:23 +0800264 public void onAirplaneModeChanged() {
265 synchronized (this) {
266 if (isBluetoothPersistedStateOn()) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800267 if (isAirplaneModeOn()) {
Ugo Yufd8efab2019-10-16 20:27:23 +0800268 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
269 } else {
270 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Ajay Panicker467bc042017-02-22 12:23:15 -0800271 }
272 }
Ugo Yufd8efab2019-10-16 20:27:23 +0800273
274 int st = BluetoothAdapter.STATE_OFF;
275 try {
276 mBluetoothLock.readLock().lock();
277 if (mBluetooth != null) {
278 st = mBluetooth.getState();
279 }
280 } catch (RemoteException e) {
281 Slog.e(TAG, "Unable to call getState", e);
282 return;
283 } finally {
284 mBluetoothLock.readLock().unlock();
285 }
286
287 Slog.d(TAG,
288 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
289 st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
290
291 if (isAirplaneModeOn()) {
292 // Clear registered LE apps to force shut-off
293 clearBleApps();
294
295 // If state is BLE_ON make sure we trigger disableBLE
296 if (st == BluetoothAdapter.STATE_BLE_ON) {
297 try {
298 mBluetoothLock.readLock().lock();
299 if (mBluetooth != null) {
300 addActiveLog(
301 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
302 mContext.getPackageName(), false);
303 mBluetooth.onBrEdrDown();
304 mEnable = false;
305 mEnableExternal = false;
306 }
307 } catch (RemoteException e) {
308 Slog.e(TAG, "Unable to call onBrEdrDown", e);
309 } finally {
310 mBluetoothLock.readLock().unlock();
311 }
312 } else if (st == BluetoothAdapter.STATE_ON) {
313 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
314 mContext.getPackageName());
315 }
316 } else if (mEnableExternal) {
317 sendEnableMsg(mQuietEnableExternal,
318 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
319 mContext.getPackageName());
320 }
Ajay Panicker467bc042017-02-22 12:23:15 -0800321 }
Ugo Yufd8efab2019-10-16 20:27:23 +0800322 }
Ajay Panicker467bc042017-02-22 12:23:15 -0800323
fredcbf072a72012-05-09 16:52:50 -0700324 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700325 @Override
326 public void onReceive(Context context, Intent intent) {
327 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700328 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700329 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800330 if (DBG) {
331 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
332 }
fredc0f420372012-04-12 00:02:00 -0700333 if (newName != null) {
334 storeNameAndAddress(newName, null);
335 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700336 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
337 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
338 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800339 if (DBG) {
340 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
341 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700342 storeNameAndAddress(null, newAddress);
343 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800344 if (DBG) {
345 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
346 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700347 }
Stanley Tng873b5702017-05-01 21:27:31 -0700348 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
349 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
350 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
351 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800352 final String prevValue =
353 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
354 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700355
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800356 if (DBG) {
357 Slog.d(TAG,
358 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
359 + ", newValue=" + newValue);
360 }
Stanley Tng873b5702017-05-01 21:27:31 -0700361
362 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
363 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800364 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
365 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700366 mHandler.sendMessage(msg);
367 }
368 }
fredc0f420372012-04-12 00:02:00 -0700369 }
370 }
371 };
372
373 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700374 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700375
fredc0f420372012-04-12 00:02:00 -0700376 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700377
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700378 mWirelessConsentRequired = context.getResources()
379 .getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700380
Marie Janssene54b4222017-03-16 18:10:59 -0700381 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700382 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800383 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800384 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700385 mBinding = false;
386 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700387 mEnable = false;
388 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800389 mQuietEnableExternal = false;
390 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700391 mAddress = null;
392 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800393 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700394 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700395 // Observe BLE scan only mode settings change.
396 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700397 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
398 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700399
Stanley Tng61dbd812019-01-13 16:04:31 -0800400 mIsHearingAidProfileSupported = context.getResources()
401 .getBoolean(com.android.internal.R.bool.config_hearing_aid_profile_supported);
402
Stanley Tngfe8c8332018-06-19 08:48:10 -0700403 // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
Stanley Tngfe8c8332018-06-19 08:48:10 -0700404 String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
405 if (!TextUtils.isEmpty(value)) {
Stanley Tng61dbd812019-01-13 16:04:31 -0800406 boolean isHearingAidEnabled = Boolean.parseBoolean(value);
Stanley Tngfe8c8332018-06-19 08:48:10 -0700407 Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
408 FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
Stanley Tng61dbd812019-01-13 16:04:31 -0800409 if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
410 // Overwrite to enable support by FeatureFlag
411 mIsHearingAidProfileSupported = true;
412 }
Stanley Tngfe8c8332018-06-19 08:48:10 -0700413 }
414
Stanley Tng873b5702017-05-01 21:27:31 -0700415 IntentFilter filter = new IntentFilter();
416 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
417 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
418 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700419 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700420 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700421
fredc0f420372012-04-12 00:02:00 -0700422 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800423 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800424 if (DBG) {
425 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
426 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800427 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700428 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200429
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800430 String airplaneModeRadios =
431 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
432 if (airplaneModeRadios == null || airplaneModeRadios.contains(
433 Settings.Global.RADIO_BLUETOOTH)) {
Ugo Yufd8efab2019-10-16 20:27:23 +0800434 mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
435 this, IoThread.get().getLooper(), context);
Ajay Panicker467bc042017-02-22 12:23:15 -0800436 }
437
Marie Janssen59804562016-12-28 14:13:21 -0800438 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200439 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800440 // Check if device is configured with no home screen, which implies no SystemUI.
441 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
442 if (!noHome) {
443 systemUiUid = mContext.getPackageManager()
444 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
445 UserHandle.USER_SYSTEM);
446 }
447 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200448 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700449 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700450 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200451 }
Marie Janssen59804562016-12-28 14:13:21 -0800452 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700453 }
454
fredc649fe492012-04-19 01:07:18 -0700455 /**
456 * Returns true if airplane mode is currently on
457 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800458 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700459 return Settings.Global.getInt(mContext.getContentResolver(),
460 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700461 }
462
Arthur Hsu2433baf2018-01-11 11:05:11 -0800463 private boolean supportBluetoothPersistedState() {
464 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
465 }
466
fredc649fe492012-04-19 01:07:18 -0700467 /**
468 * Returns true if the Bluetooth saved state is "on"
469 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800470 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800471 if (!supportBluetoothPersistedState()) {
472 return false;
473 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800474 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
475 if (DBG) {
476 Slog.d(TAG, "Bluetooth persisted state: " + state);
477 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700478 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800479 }
480
Ugo Yufd8efab2019-10-16 20:27:23 +0800481 private boolean isBluetoothPersistedStateOnAirplane() {
482 if (!supportBluetoothPersistedState()) {
483 return false;
484 }
485 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
486 if (DBG) {
487 Slog.d(TAG, "Bluetooth persisted state: " + state);
488 }
489 return state == BLUETOOTH_ON_AIRPLANE;
490 }
491
Zhihai Xu401202b2012-12-03 11:36:21 -0800492 /**
493 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
494 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800495 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800496 if (!supportBluetoothPersistedState()) {
497 return false;
498 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800499 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
500 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700501 }
502
503 /**
504 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700505 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800506 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800507 if (DBG) {
508 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
509 }
Marie Janssenfa630682016-12-15 13:51:30 -0800510 // waive WRITE_SECURE_SETTINGS permission check
511 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800512 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800513 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700514 }
515
516 /**
517 * Returns true if the Bluetooth Adapter's name and address is
518 * locally cached
519 * @return
520 */
fredc0f420372012-04-12 00:02:00 -0700521 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800522 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700523 }
524
fredc649fe492012-04-19 01:07:18 -0700525 /**
526 * Retrieve the Bluetooth Adapter's name and address and save it in
527 * in the local cache
528 */
fredc0f420372012-04-12 00:02:00 -0700529 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800530 if (DBG) {
531 Slog.d(TAG, "Loading stored name and address");
532 }
533 if (mContext.getResources()
534 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
535 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
536 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700537 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800538 if (DBG) {
539 Slog.d(TAG, "invalid bluetooth name and address stored");
540 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700541 return;
542 }
fredc0f420372012-04-12 00:02:00 -0700543 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
544 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800545 if (DBG) {
546 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
547 }
fredc0f420372012-04-12 00:02:00 -0700548 }
549
fredc649fe492012-04-19 01:07:18 -0700550 /**
551 * Save the Bluetooth name and address in the persistent store.
552 * Only non-null values will be saved.
553 * @param name
554 * @param address
555 */
fredc0f420372012-04-12 00:02:00 -0700556 private void storeNameAndAddress(String name, String address) {
557 if (name != null) {
558 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700559 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800560 if (DBG) {
561 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
562 SECURE_SETTINGS_BLUETOOTH_NAME));
563 }
fredc0f420372012-04-12 00:02:00 -0700564 }
565
566 if (address != null) {
567 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800568 mAddress = address;
569 if (DBG) {
570 Slog.d(TAG,
571 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
572 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
573 }
fredc0f420372012-04-12 00:02:00 -0700574 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700575
576 if ((name != null) && (address != null)) {
577 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
578 }
fredc0f420372012-04-12 00:02:00 -0700579 }
580
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800581 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700582 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700583 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700584 return null;
585 }
fredc0f420372012-04-12 00:02:00 -0700586 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
587 msg.obj = callback;
588 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700589
590 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700591 }
592
593 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700594 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700595 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700596 return;
597 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800598 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700599 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
600 msg.obj = callback;
601 mHandler.sendMessage(msg);
602 }
603
604 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800605 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800606 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800607 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
608 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800609 }
fredc0f420372012-04-12 00:02:00 -0700610 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
611 msg.obj = callback;
612 mHandler.sendMessage(msg);
613 }
614
615 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800616 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800617 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800618 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
619 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800620 }
fredc0f420372012-04-12 00:02:00 -0700621 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
622 msg.obj = callback;
623 mHandler.sendMessage(msg);
624 }
625
626 public boolean isEnabled() {
Zach Johnson76236d72019-11-26 21:30:07 -0800627 return getState() == BluetoothAdapter.STATE_ON;
fredc0f420372012-04-12 00:02:00 -0700628 }
629
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700630 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800631 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800632 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700633 return BluetoothAdapter.STATE_OFF;
634 }
635
636 try {
637 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800638 if (mBluetooth != null) {
639 return mBluetooth.getState();
640 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700641 } catch (RemoteException e) {
642 Slog.e(TAG, "getState()", e);
643 } finally {
644 mBluetoothLock.readLock().unlock();
645 }
646 return BluetoothAdapter.STATE_OFF;
647 }
648
Nitin Arorad055adb2015-03-02 15:03:51 -0800649 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800650 private String mPackageName;
651
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800652 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800653 mPackageName = packageName;
654 }
655
Nitin Arorad055adb2015-03-02 15:03:51 -0800656 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800657 if (DBG) {
658 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800659 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700660
661 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
662 IBinder token = entry.getKey();
663 ClientDeathRecipient deathRec = entry.getValue();
664 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700665 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700666 break;
667 }
668 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800669 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800670
Marie Janssen59804562016-12-28 14:13:21 -0800671 public String getPackageName() {
672 return mPackageName;
673 }
674 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800675
Wei Wang67d84162015-04-26 17:04:29 -0700676 @Override
677 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700678 if (isAirplaneModeOn() && !mEnable) {
679 return false;
680 }
Wei Wang67d84162015-04-26 17:04:29 -0700681 try {
Jack He8caab152018-03-02 13:08:36 -0800682 return Settings.Global.getInt(mContentResolver,
683 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700684 } catch (SettingNotFoundException e) {
685 }
686 return false;
687 }
688
Stanley Tng61dbd812019-01-13 16:04:31 -0800689 @Override
690 public boolean isHearingAidProfileSupported() {
691 return mIsHearingAidProfileSupported;
692 }
693
Wei Wange4a744b2015-06-11 17:50:29 -0700694 // Monitor change of BLE scan only mode settings.
695 private void registerForBleScanModeChange() {
696 ContentObserver contentObserver = new ContentObserver(null) {
697 @Override
698 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800699 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800700 // Nothing to do
701 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800702 }
703 // BLE scan is not available.
704 disableBleScanMode();
705 clearBleApps();
706 try {
707 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800708 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700709 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
710 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800711 mBluetooth.onBrEdrDown();
712 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800713 } catch (RemoteException e) {
714 Slog.e(TAG, "error when disabling bluetooth", e);
715 } finally {
716 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700717 }
718 }
719 };
720
721 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800722 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
723 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700724 }
725
726 // Disable ble scan only mode.
727 private void disableBleScanMode() {
728 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700729 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700730 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800731 if (DBG) {
732 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
733 }
Wei Wange4a744b2015-06-11 17:50:29 -0700734 mEnable = false;
735 }
736 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700737 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700738 } finally {
739 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700740 }
741 }
742
Marie Janssen59804562016-12-28 14:13:21 -0800743 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
Jack Hea80cead2019-04-23 20:00:18 -0700744 // Check if packageName belongs to callingUid
745 final int callingUid = Binder.getCallingUid();
746 final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
747 if (!isCallerSystem) {
748 checkPackage(callingUid, packageName);
749 }
Marie Janssen59804562016-12-28 14:13:21 -0800750 ClientDeathRecipient r = mBleApps.get(token);
751 if (r == null && enable) {
752 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
753 try {
754 token.linkToDeath(deathRec, 0);
755 } catch (RemoteException ex) {
756 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800757 }
Marie Janssen59804562016-12-28 14:13:21 -0800758 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800759 if (DBG) {
760 Slog.d(TAG, "Registered for death of " + packageName);
761 }
Marie Janssen59804562016-12-28 14:13:21 -0800762 } else if (!enable && r != null) {
763 // Unregister death recipient as the app goes away.
764 token.unlinkToDeath(r, 0);
765 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800766 if (DBG) {
767 Slog.d(TAG, "Unregistered for death of " + packageName);
768 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800769 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800770 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800771 if (DBG) {
772 Slog.d(TAG, appCount + " registered Ble Apps");
773 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800774 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700775 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800777 if (appCount == 0 && !mEnableExternal) {
778 sendBrEdrDownCallback();
779 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800780 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800781 }
782
Wei Wange4a744b2015-06-11 17:50:29 -0700783 // Clear all apps using BLE scan only mode.
784 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800785 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700786 }
787
Marie Janssen59804562016-12-28 14:13:21 -0800788 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800789 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800790 if (DBG) {
791 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
792 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800793 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800794 }
795
796 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700797 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800798 */
Myles Watson304ebf22018-05-11 08:47:24 -0700799 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800800 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700801 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800802 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700803 try {
804 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800805 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700806 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800807 return;
808 }
809 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
810 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800811 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800812 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800813 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700814 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800815 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700816 } finally {
817 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800818 }
819 }
820
821 /**
822 * Inform BluetoothAdapter instances that BREDR part is down
823 * and turn off all service and stack if no LE app needs it
824 */
825 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800826 if (DBG) {
827 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
828 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700829
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700830 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700831 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700832 return;
833 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800834
Martin Brabhamc2b06222017-02-27 16:55:07 -0800835 if (isBleAppPresent()) {
836 // Need to stay at BLE ON. Disconnect all Gatt connections
837 try {
838 mBluetoothGatt.unregAll();
839 } catch (RemoteException e) {
840 Slog.e(TAG, "Unable to disconnect all apps.", e);
841 }
842 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800843 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700844 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800845 if (mBluetooth != null) {
846 mBluetooth.onBrEdrDown();
847 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700848 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700849 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700850 } finally {
851 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800852 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800853 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800854
Nitin Arorad055adb2015-03-02 15:03:51 -0800855 }
856
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800857 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100858 if (isBluetoothDisallowed()) {
859 if (DBG) {
860 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
861 }
862 return false;
863 }
864
Jack Hea80cead2019-04-23 20:00:18 -0700865 // Check if packageName belongs to callingUid
866 final int callingUid = Binder.getCallingUid();
867 final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
868 if (!isCallerSystem) {
869 checkPackage(callingUid, packageName);
870 }
871
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700872 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800873 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700874
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700875 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800876 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
877 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700878 }
Jack Hea80cead2019-04-23 20:00:18 -0700879 int callingAppId = UserHandle.getAppId(callingUid);
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800880
881 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700882 throw new SecurityException("no permission to enable Bluetooth quietly");
883 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800884
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800885 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800886 mQuietEnableExternal = true;
887 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800888 sendEnableMsg(true,
889 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800890 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700891 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700892 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700893
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700894 public boolean enable(String packageName) throws RemoteException {
895 final int callingUid = Binder.getCallingUid();
896 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
897
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100898 if (isBluetoothDisallowed()) {
899 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800900 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100901 }
902 return false;
903 }
904
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700905 if (!callerSystem) {
Jack Hea80cead2019-04-23 20:00:18 -0700906 // Check if packageName belongs to callingUid
907 checkPackage(callingUid, packageName);
908
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700909 if (!checkIfCallerIsForegroundUser()) {
910 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
911 return false;
912 }
913
914 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
915 "Need BLUETOOTH ADMIN permission");
916
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700917 if (!isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800918 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700919 return false;
920 }
fredcf2458862012-04-16 15:18:27 -0700921 }
922
Zhihai Xu401202b2012-12-03 11:36:21 -0800923 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800924 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
925 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700926 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800927
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800928 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800929 mQuietEnableExternal = false;
930 mEnableExternal = true;
931 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800932 sendEnableMsg(false,
933 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800934 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800935 if (DBG) {
936 Slog.d(TAG, "enable returning");
937 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800938 return true;
fredc0f420372012-04-12 00:02:00 -0700939 }
940
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700941 public boolean disable(String packageName, boolean persist) throws RemoteException {
942 final int callingUid = Binder.getCallingUid();
943 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700944
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700945 if (!callerSystem) {
Jack Hea80cead2019-04-23 20:00:18 -0700946 // Check if packageName belongs to callingUid
947 checkPackage(callingUid, packageName);
948
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700949 if (!checkIfCallerIsForegroundUser()) {
950 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
951 return false;
952 }
953
954 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
955 "Need BLUETOOTH ADMIN permission");
956
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700957 if (isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800958 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700959 return false;
960 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700961 }
962
fredcf2458862012-04-16 15:18:27 -0700963 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800964 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700965 }
fredcf2458862012-04-16 15:18:27 -0700966
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800967 synchronized (mReceiver) {
Ugo Yufd8efab2019-10-16 20:27:23 +0800968 if (!isBluetoothPersistedStateOnAirplane()) {
969 if (persist) {
970 persistBluetoothSetting(BLUETOOTH_OFF);
971 }
972 mEnableExternal = false;
Zhihai Xu401202b2012-12-03 11:36:21 -0800973 }
Jack He8caab152018-03-02 13:08:36 -0800974 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
975 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800976 }
fredc0f420372012-04-12 00:02:00 -0700977 return true;
978 }
979
baishengf62d8692018-01-25 18:07:24 +0800980 private boolean startConsentUiIfNeeded(String packageName,
981 int callingUid, String intentAction) throws RemoteException {
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700982 if (checkBluetoothPermissionWhenWirelessConsentRequired()) {
baishengf62d8692018-01-25 18:07:24 +0800983 return false;
984 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700985 try {
986 // Validate the package only if we are going to use it
987 ApplicationInfo applicationInfo = mContext.getPackageManager()
988 .getApplicationInfoAsUser(packageName,
989 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
990 UserHandle.getUserId(callingUid));
991 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800992 throw new SecurityException("Package " + packageName
993 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700994 }
995
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000996 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000997 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800998 intent.setFlags(
999 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +00001000 try {
1001 mContext.startActivity(intent);
1002 } catch (ActivityNotFoundException e) {
1003 // Shouldn't happen
1004 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
1005 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -07001006 }
Ivan Podogov1ab87252017-01-03 12:02:18 +00001007 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -07001008 } catch (PackageManager.NameNotFoundException e) {
1009 throw new RemoteException(e.getMessage());
1010 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -07001011 }
1012
baishengf62d8692018-01-25 18:07:24 +08001013 /**
Jack Hea80cead2019-04-23 20:00:18 -07001014 * Check if AppOpsManager is available and the packageName belongs to uid
1015 *
1016 * A null package belongs to any uid
1017 */
1018 private void checkPackage(int uid, String packageName) {
1019 if (mAppOps == null) {
1020 Slog.w(TAG, "checkPackage(): called before system boot up, uid "
1021 + uid + ", packageName " + packageName);
1022 throw new IllegalStateException("System has not boot yet");
1023 }
1024 if (packageName == null) {
1025 Slog.w(TAG, "checkPackage(): called with null packageName from " + uid);
1026 return;
1027 }
1028 try {
1029 mAppOps.checkPackage(uid, packageName);
1030 } catch (SecurityException e) {
1031 Slog.w(TAG, "checkPackage(): " + packageName + " does not belong to uid " + uid);
Jack Hea80cead2019-04-23 20:00:18 -07001032 throw new SecurityException(e.getMessage());
1033 }
1034 }
1035
1036 /**
baishengf62d8692018-01-25 18:07:24 +08001037 * Check if the caller must still pass permission check or if the caller is exempted
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001038 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED check.
baishengf62d8692018-01-25 18:07:24 +08001039 *
1040 * Commands from some callers may be exempted from triggering the consent UI when
1041 * enabling bluetooth. This exemption is checked via the
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001042 * MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED and allows calls to skip
baishengf62d8692018-01-25 18:07:24 +08001043 * the consent UI where it may otherwise be required.
1044 *
1045 * @hide
1046 */
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001047 private boolean checkBluetoothPermissionWhenWirelessConsentRequired() {
baishengf62d8692018-01-25 18:07:24 +08001048 int result = mContext.checkCallingPermission(
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001049 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED);
baishengf62d8692018-01-25 18:07:24 +08001050 return result == PackageManager.PERMISSION_GRANTED;
1051 }
1052
fredc649fe492012-04-19 01:07:18 -07001053 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -07001054 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001055 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
1056 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -07001057 }
1058
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001059 try {
1060 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001061 if (mUnbinding) {
1062 return;
1063 }
fredc0f420372012-04-12 00:02:00 -07001064 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001065 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001066 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001067 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001068 //Unregister callback object
1069 try {
1070 mBluetooth.unregisterCallback(mBluetoothCallback);
1071 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001072 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001073 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001074 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001075 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001076 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001077 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001078 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001079 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001080 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001081 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001082 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001083 } finally {
1084 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001085 }
1086 }
1087
Matthew Xieddf7e472013-03-01 18:41:02 -08001088 public IBluetoothGatt getBluetoothGatt() {
1089 // sync protection
1090 return mBluetoothGatt;
1091 }
1092
Benjamin Franze8b98922014-11-12 15:57:54 +00001093 @Override
1094 public boolean bindBluetoothProfileService(int bluetoothProfile,
1095 IBluetoothProfileServiceConnection proxy) {
1096 if (!mEnable) {
1097 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001098 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1099 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001100 }
1101 return false;
1102 }
1103 synchronized (mProfileServices) {
1104 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1105 if (psc == null) {
1106 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001107 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1108 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001109 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001110
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001111 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1112 return false;
1113 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001114
1115 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001116 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001117 if (!psc.bindService()) {
1118 return false;
1119 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001120
Benjamin Franze8b98922014-11-12 15:57:54 +00001121 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001122 }
1123 }
1124
1125 // Introducing a delay to give the client app time to prepare
1126 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1127 addProxyMsg.arg1 = bluetoothProfile;
1128 addProxyMsg.obj = proxy;
1129 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1130 return true;
1131 }
1132
1133 @Override
1134 public void unbindBluetoothProfileService(int bluetoothProfile,
1135 IBluetoothProfileServiceConnection proxy) {
1136 synchronized (mProfileServices) {
Ugo Yu6d9cfce2019-03-26 21:38:08 +08001137 Integer profile = new Integer(bluetoothProfile);
1138 ProfileServiceConnections psc = mProfileServices.get(profile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001139 if (psc == null) {
1140 return;
1141 }
1142 psc.removeProxy(proxy);
Ugo Yu6d9cfce2019-03-26 21:38:08 +08001143 if (psc.isEmpty()) {
1144 // All prxoies are disconnected, unbind with the service.
1145 try {
1146 mContext.unbindService(psc);
1147 } catch (IllegalArgumentException e) {
1148 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
1149 }
1150 mProfileServices.remove(profile);
1151 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001152 }
1153 }
1154
1155 private void unbindAllBluetoothProfileServices() {
1156 synchronized (mProfileServices) {
1157 for (Integer i : mProfileServices.keySet()) {
1158 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001159 try {
1160 mContext.unbindService(psc);
1161 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001162 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001163 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001164 psc.removeAllProxies();
1165 }
1166 mProfileServices.clear();
1167 }
1168 }
1169
1170 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001171 * Send enable message and set adapter name and address. Called when the boot phase becomes
1172 * PHASE_SYSTEM_SERVICES_READY.
1173 */
1174 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001175 if (DBG) {
1176 Slog.d(TAG, "Bluetooth boot completed");
1177 }
Jack Hea80cead2019-04-23 20:00:18 -07001178 mAppOps = mContext.getSystemService(AppOpsManager.class);
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001179 UserManagerInternal userManagerInternal =
1180 LocalServices.getService(UserManagerInternal.class);
1181 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001182 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001183 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001184 return;
1185 }
Zongheng Wang79e0bf62019-07-08 15:22:04 -07001186 final boolean isSafeMode = mContext.getPackageManager().isSafeMode();
1187 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && !isSafeMode) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001188 if (DBG) {
1189 Slog.d(TAG, "Auto-enabling Bluetooth.");
1190 }
Jack He8caab152018-03-02 13:08:36 -08001191 sendEnableMsg(mQuietEnableExternal,
1192 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1193 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001194 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001195 if (DBG) {
1196 Slog.d(TAG, "Getting adapter name and address");
1197 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001198 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1199 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001200 }
Ugo Yufd8efab2019-10-16 20:27:23 +08001201 if (mBluetoothAirplaneModeListener != null) {
1202 mBluetoothAirplaneModeListener.start(
1203 new BluetoothAirplaneModeListener.AirplaneModeHelper(mContext));
1204 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001205 }
1206
1207 /**
1208 * Called when switching to a different foreground user.
1209 */
1210 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001211 if (DBG) {
1212 Slog.d(TAG, "User " + userHandle + " switched");
1213 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001214 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1215 }
1216
1217 /**
1218 * Called when user is unlocked.
1219 */
1220 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001221 if (DBG) {
1222 Slog.d(TAG, "User " + userHandle + " unlocked");
1223 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001224 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001225 }
1226
1227 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001228 * This class manages the clients connected to a given ProfileService
1229 * and maintains the connection with that service.
1230 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001231 private final class ProfileServiceConnections
1232 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001233 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001234 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001235 IBinder mService;
1236 ComponentName mClassName;
1237 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001238 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001239
1240 ProfileServiceConnections(Intent intent) {
1241 mService = null;
1242 mClassName = null;
1243 mIntent = intent;
1244 }
1245
Benjamin Franz5b614592014-12-09 18:58:45 +00001246 private boolean bindService() {
jonerlin37fc85d2018-08-09 16:39:43 +08001247 int state = BluetoothAdapter.STATE_OFF;
1248 try {
1249 mBluetoothLock.readLock().lock();
1250 if (mBluetooth != null) {
1251 state = mBluetooth.getState();
1252 }
1253 } catch (RemoteException e) {
1254 Slog.e(TAG, "Unable to call getState", e);
1255 return false;
1256 } finally {
1257 mBluetoothLock.readLock().unlock();
1258 }
1259
1260 if (!mEnable || state != BluetoothAdapter.STATE_ON) {
1261 if (DBG) {
1262 Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
1263 }
1264 return false;
1265 }
1266
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001267 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1268 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001269 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1270 msg.obj = this;
1271 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001272 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001273 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001274 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001275 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001276 }
1277
1278 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1279 mProxies.register(proxy);
1280 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001281 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001282 proxy.onServiceConnected(mClassName, mService);
1283 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001284 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001285 }
1286 } else {
1287 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1288 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1289 msg.obj = this;
1290 mHandler.sendMessage(msg);
1291 }
1292 }
1293 }
1294
1295 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1296 if (proxy != null) {
1297 if (mProxies.unregister(proxy)) {
1298 try {
1299 proxy.onServiceDisconnected(mClassName);
1300 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001301 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001302 }
1303 }
1304 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001305 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001306 }
1307 }
1308
1309 private void removeAllProxies() {
1310 onServiceDisconnected(mClassName);
1311 mProxies.kill();
1312 }
1313
Ugo Yu6d9cfce2019-03-26 21:38:08 +08001314 private boolean isEmpty() {
1315 return mProxies.getRegisteredCallbackCount() == 0;
1316 }
1317
Benjamin Franze8b98922014-11-12 15:57:54 +00001318 @Override
1319 public void onServiceConnected(ComponentName className, IBinder service) {
1320 // remove timeout message
1321 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1322 mService = service;
1323 mClassName = className;
1324 try {
1325 mService.linkToDeath(this, 0);
1326 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001327 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001328 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001329
1330 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001331 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001332 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001333 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001334 mInvokingProxyCallbacks = true;
1335
1336 final int n = mProxies.beginBroadcast();
1337 try {
1338 for (int i = 0; i < n; i++) {
1339 try {
1340 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1341 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001342 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001343 }
1344 }
1345 } finally {
1346 mProxies.finishBroadcast();
1347 mInvokingProxyCallbacks = false;
1348 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001349 }
1350
1351 @Override
1352 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001353 if (mService == null) {
1354 return;
1355 }
Chienyuan177156b2018-12-18 10:40:25 +08001356 try {
1357 mService.unlinkToDeath(this, 0);
1358 } catch (NoSuchElementException e) {
1359 Log.e(TAG, "error unlinking to death", e);
1360 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001361 mService = null;
1362 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001363
1364 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001365 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001366 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001367 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001368 mInvokingProxyCallbacks = true;
1369
1370 final int n = mProxies.beginBroadcast();
1371 try {
1372 for (int i = 0; i < n; i++) {
1373 try {
1374 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1375 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001376 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001377 }
1378 }
1379 } finally {
1380 mProxies.finishBroadcast();
1381 mInvokingProxyCallbacks = false;
1382 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001383 }
1384
1385 @Override
1386 public void binderDied() {
1387 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001388 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001389 }
1390 onServiceDisconnected(mClassName);
1391 // Trigger rebind
1392 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1393 msg.obj = this;
1394 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1395 }
1396 }
1397
fredcbf072a72012-05-09 16:52:50 -07001398 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001399 try {
1400 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001401 if (DBG) {
1402 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1403 + " receivers.");
1404 }
1405 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001406 try {
1407 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1408 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001409 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001410 }
fredcbf072a72012-05-09 16:52:50 -07001411 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001412 } finally {
1413 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001414 }
fredcbf072a72012-05-09 16:52:50 -07001415 }
1416
1417 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001418 * Inform BluetoothAdapter instances that Adapter service is up
1419 */
1420 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001421 try {
1422 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001423 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1424 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001425 try {
1426 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001427 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001428 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001429 }
1430 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001431 } finally {
1432 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001433 }
1434 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001435
Zhihai Xu40874a02012-10-08 17:57:03 -07001436 /**
fredcbf072a72012-05-09 16:52:50 -07001437 * Inform BluetoothAdapter instances that Adapter service is down
1438 */
1439 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001440 try {
1441 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001442 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1443 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001444 try {
1445 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001446 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001447 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001448 }
1449 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001450 } finally {
1451 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001452 }
1453 }
Svet Ganov408abf72015-05-12 19:13:36 -07001454
fredc0f420372012-04-12 00:02:00 -07001455 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001456 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001457
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001458 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1459 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001460 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001461 }
1462
Svet Ganov408abf72015-05-12 19:13:36 -07001463 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1464 != PackageManager.PERMISSION_GRANTED) {
1465 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1466 }
1467
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001468 try {
1469 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001470 if (mBluetooth != null) {
1471 return mBluetooth.getAddress();
1472 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001473 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001474 Slog.e(TAG,
1475 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1476 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001477 } finally {
1478 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001479 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001480
Matthew Xiecdce0b92012-07-12 19:06:15 -07001481 // mAddress is accessed from outside.
1482 // It is alright without a lock. Here, bluetooth is off, no other thread is
1483 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001484 return mAddress;
1485 }
fredc649fe492012-04-19 01:07:18 -07001486
fredc0f420372012-04-12 00:02:00 -07001487 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001488 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001489
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001490 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1491 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001492 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001493 }
1494
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001495 try {
1496 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001497 if (mBluetooth != null) {
1498 return mBluetooth.getName();
1499 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001500 } catch (RemoteException e) {
1501 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1502 } finally {
1503 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001504 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001505
Matthew Xiecdce0b92012-07-12 19:06:15 -07001506 // mName is accessed from outside.
1507 // It alright without a lock. Here, bluetooth is off, no other thread is
1508 // changing mName
fredc0f420372012-04-12 00:02:00 -07001509 return mName;
1510 }
1511
fredc0f420372012-04-12 00:02:00 -07001512 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001513 public void onServiceConnected(ComponentName componentName, IBinder service) {
1514 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001515 if (DBG) {
1516 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1517 }
fredc0f420372012-04-12 00:02:00 -07001518 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001519 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001520 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001521 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001522 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1523 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001524 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001525 return;
1526 }
fredc0f420372012-04-12 00:02:00 -07001527 msg.obj = service;
1528 mHandler.sendMessage(msg);
1529 }
1530
Marie Janssencb21ad72016-12-13 10:51:02 -08001531 public void onServiceDisconnected(ComponentName componentName) {
1532 // Called if we unexpectedly disconnect.
1533 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001534 if (DBG) {
1535 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1536 }
fredc0f420372012-04-12 00:02:00 -07001537 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001538 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001539 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001540 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001541 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1542 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001543 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001544 return;
1545 }
fredc0f420372012-04-12 00:02:00 -07001546 mHandler.sendMessage(msg);
1547 }
1548 }
1549
1550 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1551
Zhihai Xu40874a02012-10-08 17:57:03 -07001552 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001553 boolean mGetNameAddressOnly = false;
1554
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001555 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001556 super(looper);
1557 }
1558
fredc0f420372012-04-12 00:02:00 -07001559 @Override
1560 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001561 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001562 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001563 if (DBG) {
1564 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1565 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001566 try {
1567 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001568 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001569 if (DBG) {
1570 Slog.d(TAG, "Binding to service to get name and address");
1571 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001572 mGetNameAddressOnly = true;
1573 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1574 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1575 Intent i = new Intent(IBluetooth.class.getName());
1576 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001577 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1578 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001579 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1580 } else {
1581 mBinding = true;
1582 }
1583 } else if (mBluetooth != null) {
1584 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001585 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001586 } catch (RemoteException re) {
1587 Slog.e(TAG, "Unable to grab names", re);
1588 }
1589 if (mGetNameAddressOnly && !mEnable) {
1590 unbindAndFinish();
1591 }
1592 mGetNameAddressOnly = false;
1593 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001594 } finally {
1595 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001596 }
1597 break;
1598
Matthew Xiecdce0b92012-07-12 19:06:15 -07001599 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001600 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001601 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001602 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001603 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1604 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001605
1606 // Use service interface to get the exact state
1607 try {
1608 mBluetoothLock.readLock().lock();
1609 if (mBluetooth != null) {
1610 int state = mBluetooth.getState();
1611 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001612 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001613 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001614 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001615 break;
1616 }
1617 }
1618 } catch (RemoteException e) {
1619 Slog.e(TAG, "", e);
1620 } finally {
1621 mBluetoothLock.readLock().unlock();
1622 }
1623
1624 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001625 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001626 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001627 } else {
1628 //
1629 // We need to wait until transitioned to STATE_OFF and
1630 // the previous Bluetooth process has exited. The
1631 // waiting period has three components:
1632 // (a) Wait until the local state is STATE_OFF. This
1633 // is accomplished by "waitForOnOff(false, true)".
1634 // (b) Wait until the STATE_OFF state is updated to
1635 // all components.
1636 // (c) Wait until the Bluetooth process exits, and
1637 // ActivityManager detects it.
1638 // The waiting for (b) and (c) is accomplished by
1639 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
Ugo Yu1ff6fd32019-11-20 17:59:11 +08001640 // message. The delay time is backed off if Bluetooth
1641 // continuously failed to turn on itself.
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001642 //
1643 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001644 Message restartMsg =
1645 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Ugo Yu1ff6fd32019-11-20 17:59:11 +08001646 mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001647 }
fredc649fe492012-04-19 01:07:18 -07001648 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001649
fredc0f420372012-04-12 00:02:00 -07001650 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001651 if (DBG) {
1652 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1653 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001654 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1655 if (mEnable && mBluetooth != null) {
1656 waitForOnOff(true, false);
1657 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001658 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001659 waitForOnOff(false, false);
1660 } else {
1661 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001662 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001663 }
fredc0f420372012-04-12 00:02:00 -07001664 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001665
Stanley Tng873b5702017-05-01 21:27:31 -07001666 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001667 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1668 if (DBG) {
1669 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001670 }
Jack He8caab152018-03-02 13:08:36 -08001671 persistBluetoothSetting(BLUETOOTH_OFF);
1672 mEnableExternal = false;
1673 sendDisableMsg(
1674 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1675 mContext.getPackageName());
1676 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1677 if (DBG) {
1678 Slog.d(TAG, "Restore Bluetooth state to enabled");
1679 }
1680 mQuietEnableExternal = false;
1681 mEnableExternal = true;
1682 // waive WRITE_SECURE_SETTINGS permission check
1683 sendEnableMsg(false,
1684 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1685 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001686 }
1687 break;
1688
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001689 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001690 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001691 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001692 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001693 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001694 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001695 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001696 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001697 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001698 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001699 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1700 IBluetoothStateChangeCallback callback =
1701 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001702 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001703 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001704 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001705 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1706 IBluetoothStateChangeCallback callback =
1707 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001708 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001709 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001710 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001711 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001712 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001713 if (psc == null) {
1714 break;
1715 }
1716 IBluetoothProfileServiceConnection proxy =
1717 (IBluetoothProfileServiceConnection) msg.obj;
1718 psc.addProxy(proxy);
1719 break;
1720 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001721 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001722 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1723 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1724 if (psc == null) {
1725 break;
1726 }
1727 psc.bindService();
1728 break;
1729 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001730 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1731 if (DBG) {
1732 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1733 }
fredc0f420372012-04-12 00:02:00 -07001734
1735 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001736 try {
1737 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001738 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001739 mBluetoothGatt =
1740 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001741 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001742 break;
1743 } // else must be SERVICE_IBLUETOOTH
1744
1745 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001746 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001747
fredc0f420372012-04-12 00:02:00 -07001748 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001749 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001750 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001751
Ajay Panicker4bb48302016-03-31 14:14:27 -07001752 if (!isNameAndAddressSet()) {
1753 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1754 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001755 if (mGetNameAddressOnly) {
1756 return;
1757 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001758 }
1759
Matthew Xiecdce0b92012-07-12 19:06:15 -07001760 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001761 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001762 mBluetooth.registerCallback(mBluetoothCallback);
1763 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001764 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001765 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001766 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001767 sendBluetoothServiceUpCallback();
1768
Matthew Xiecdce0b92012-07-12 19:06:15 -07001769 //Do enable request
1770 try {
Zach Johnson1c86ed12019-11-26 21:46:08 -08001771 if (!mBluetooth.enable(mQuietEnable)) {
1772 Slog.e(TAG, "IBluetooth.enable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001773 }
1774 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001775 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001776 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001777 } finally {
1778 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001779 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001780
1781 if (!mEnable) {
1782 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001783 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001784 waitForOnOff(false, false);
1785 }
fredc649fe492012-04-19 01:07:18 -07001786 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001787 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001788 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001789 int prevState = msg.arg1;
1790 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001791 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001792 Slog.d(TAG,
1793 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1794 prevState) + " > " + BluetoothAdapter.nameForState(
1795 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001796 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001797 mState = newState;
1798 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001799 // handle error state transition case from TURNING_ON to OFF
1800 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001801 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1802 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001803 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001804 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001805 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1806 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001807 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001808 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001809 // If we tried to enable BT while BT was in the process of shutting down,
1810 // wait for the BT process to fully tear down and then force a restart
1811 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001812 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1813 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001814 if (mEnable) {
1815 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1816 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001817 Message restartMsg =
1818 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Ugo Yu1ff6fd32019-11-20 17:59:11 +08001819 mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
Calvin Ona0b91d72016-06-15 17:58:23 -07001820 }
1821 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001822 if (newState == BluetoothAdapter.STATE_ON
1823 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001824 // bluetooth is working, reset the counter
1825 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001826 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001827 mErrorRecoveryRetryCounter = 0;
1828 }
1829 }
fredc649fe492012-04-19 01:07:18 -07001830 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001831 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001832 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001833 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001834 try {
1835 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001836 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1837 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001838 if (mBluetooth == null) {
1839 break;
1840 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001841 mBluetooth = null;
1842 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1843 mBluetoothGatt = null;
1844 break;
1845 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001846 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001847 break;
1848 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001849 } finally {
1850 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301851 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001852
Marie Janssene54b4222017-03-16 18:10:59 -07001853 // log the unexpected crash
1854 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001855 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1856 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001857 if (mEnable) {
1858 mEnable = false;
1859 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001860 Message restartMsg =
1861 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Ugo Yu1ff6fd32019-11-20 17:59:11 +08001862 mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
Zhihai Xu40874a02012-10-08 17:57:03 -07001863 }
1864
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001865 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001866
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001867 // Send BT state broadcast to update
1868 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001869 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1870 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001871 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001872 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001873 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001874 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001875 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1876 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001877 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001878 }
1879
1880 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1881 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001882 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001883 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001884 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Ugo Yu1ff6fd32019-11-20 17:59:11 +08001885 mErrorRecoveryRetryCounter++;
1886 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE: retry count="
1887 + mErrorRecoveryRetryCounter);
1888 if (mErrorRecoveryRetryCounter < MAX_ERROR_RESTART_RETRIES) {
1889 /* Enable without persisting the setting as
1890 it doesnt change when IBluetooth
1891 service restarts */
1892 mEnable = true;
1893 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1894 mContext.getPackageName(), true);
1895 handleEnable(mQuietEnable);
1896 } else {
1897 Slog.e(TAG, "Reach maximum retry to restart Bluetooth!");
1898 }
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301899 break;
1900 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001901 case MESSAGE_TIMEOUT_BIND: {
1902 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1903 mBluetoothLock.writeLock().lock();
1904 mBinding = false;
1905 mBluetoothLock.writeLock().unlock();
1906 break;
1907 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001908 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001909 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001910 mBluetoothLock.writeLock().lock();
1911 mUnbinding = false;
1912 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001913 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001914 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001915
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001916 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001917 if (DBG) {
1918 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1919 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001920 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001921
Zhihai Xu40874a02012-10-08 17:57:03 -07001922 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001923 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001924 try {
1925 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001926 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001927 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001928 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001929 } catch (RemoteException re) {
1930 Slog.e(TAG, "Unable to unregister", re);
1931 } finally {
1932 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001933 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001934
1935 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1936 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1937 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1938 mState = BluetoothAdapter.STATE_OFF;
1939 }
1940 if (mState == BluetoothAdapter.STATE_OFF) {
1941 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1942 mState = BluetoothAdapter.STATE_TURNING_ON;
1943 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001944
1945 waitForOnOff(true, false);
1946
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001947 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1948 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1949 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001950
Benjamin Franze8b98922014-11-12 15:57:54 +00001951 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001952 // disable
Jack He8caab152018-03-02 13:08:36 -08001953 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1954 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001955 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001956 // Pbap service need receive STATE_TURNING_OFF intent to close
1957 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001958 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001959
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001960 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001961
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001962 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001963 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001964 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001965
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001966 try {
1967 mBluetoothLock.writeLock().lock();
1968 if (mBluetooth != null) {
1969 mBluetooth = null;
1970 // Unbind
1971 mContext.unbindService(mConnection);
1972 }
1973 mBluetoothGatt = null;
1974 } finally {
1975 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001976 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001977
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001978 //
1979 // If disabling Bluetooth times out, wait for an
1980 // additional amount of time to ensure the process is
1981 // shut down completely before attempting to restart.
1982 //
1983 if (didDisableTimeout) {
1984 SystemClock.sleep(3000);
1985 } else {
1986 SystemClock.sleep(100);
1987 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001988
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001989 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1990 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001991 // enable
Jack He8caab152018-03-02 13:08:36 -08001992 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1993 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001994 // mEnable flag could have been reset on disableBLE. Reenable it.
1995 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001996 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001997 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001998 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1999 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08002000 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07002001 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
2002 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002003 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07002004 }
John Spurlock8a985d22014-02-25 09:40:05 -05002005 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002006 break;
2007 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07002008 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002009 if (DBG) {
2010 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
2011 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07002012 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
2013
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002014 if (mEnable && !mBinding && (mBluetooth == null)) {
2015 // We should be connected, but we gave up for some
2016 // reason; maybe the Bluetooth service wasn't encryption
2017 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002018 if (DBG) {
2019 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
2020 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002021 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07002022 }
2023 }
fredc0f420372012-04-12 00:02:00 -07002024 }
2025 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002026 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07002027
Zhihai Xu401202b2012-12-03 11:36:21 -08002028 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07002029 mQuietEnable = quietMode;
2030
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002031 try {
2032 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002033 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07002034 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002035 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
2036 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07002037 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002038 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07002039 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07002040 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07002041 } else {
2042 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07002043 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002044 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07002045 //Enable bluetooth
2046 try {
Zach Johnson1c86ed12019-11-26 21:46:08 -08002047 if (!mBluetooth.enable(mQuietEnable)) {
2048 Slog.e(TAG, "IBluetooth.enable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002049 }
2050 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002051 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07002052 }
2053 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002054 } finally {
2055 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002056 }
2057 }
2058
Dianne Hackborn221ea892013-08-04 16:50:16 -07002059 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
2060 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
2061 intent.setComponent(comp);
2062 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07002063 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07002064 return false;
2065 }
2066 return true;
2067 }
2068
Zhihai Xu401202b2012-12-03 11:36:21 -08002069 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002070 try {
2071 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08002072 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002073 if (DBG) {
2074 Slog.d(TAG, "Sending off request.");
2075 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002076 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002077 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002078 }
2079 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002080 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002081 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002082 } finally {
2083 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002084 }
2085 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002086
2087 private boolean checkIfCallerIsForegroundUser() {
2088 int foregroundUser;
2089 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002090 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07002091 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00002092 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
2093 UserInfo ui = um.getProfileParent(callingUser);
2094 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002095 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07002096 boolean valid = false;
2097 try {
2098 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002099 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2100 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002101 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002102 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2103 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2104 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002105 }
2106 } finally {
2107 Binder.restoreCallingIdentity(callingIdentity);
2108 }
2109 return valid;
2110 }
2111
Nitin Arorad055adb2015-03-02 15:03:51 -08002112 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002113 if (DBG) {
2114 Slog.d(TAG,
2115 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2116 + BluetoothAdapter.nameForState(newState));
2117 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002118 // Send broadcast message to everyone else
2119 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2120 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2121 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2122 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2123 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2124 }
2125
Zhihai Xu40874a02012-10-08 17:57:03 -07002126 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002127 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002128 if (prevState == newState) { // No change. Nothing to do.
2129 return;
2130 }
2131 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002132 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002133 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002134 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002135
Marie Janssencb21ad72016-12-13 10:51:02 -08002136 if (newState == BluetoothAdapter.STATE_OFF) {
2137 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002138 if (DBG) {
2139 Slog.d(TAG, "Bluetooth is complete send Service Down");
2140 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002141 sendBluetoothServiceDownCallback();
2142 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002143 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002144 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002145 isStandardBroadcast = false;
2146
Marie Janssencb21ad72016-12-13 10:51:02 -08002147 } else if (!intermediate_off) {
2148 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002149 if (DBG) {
2150 Slog.d(TAG, "Bluetooth is in LE only mode");
2151 }
Myles Watson304ebf22018-05-11 08:47:24 -07002152 if (mBluetoothGatt != null || !mContext.getPackageManager()
2153 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2154 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002155 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002156 if (DBG) {
2157 Slog.d(TAG, "Binding Bluetooth GATT service");
2158 }
Myles Watson304ebf22018-05-11 08:47:24 -07002159 Intent i = new Intent(IBluetoothGatt.class.getName());
2160 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2161 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002162 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002163 sendBleStateChanged(prevState, newState);
2164 //Don't broadcase this as std intent
2165 isStandardBroadcast = false;
2166
2167 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002168 if (DBG) {
2169 Slog.d(TAG, "Intermediate off, back to LE only mode");
2170 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002171 // For LE only mode, broadcast as is
2172 sendBleStateChanged(prevState, newState);
2173 sendBluetoothStateCallback(false); // BT is OFF for general users
2174 // Broadcast as STATE_OFF
2175 newState = BluetoothAdapter.STATE_OFF;
2176 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002177 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002178 } else if (newState == BluetoothAdapter.STATE_ON) {
2179 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2180 sendBluetoothStateCallback(isUp);
2181 sendBleStateChanged(prevState, newState);
2182
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002183 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2184 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002185 sendBleStateChanged(prevState, newState);
2186 isStandardBroadcast = false;
2187
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002188 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2189 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002190 sendBleStateChanged(prevState, newState);
2191 }
2192
2193 if (isStandardBroadcast) {
2194 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2195 // Show prevState of BLE_ON as OFF to standard users
2196 prevState = BluetoothAdapter.STATE_OFF;
2197 }
2198 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2199 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2200 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2201 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2202 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002203 }
2204 }
2205
2206 /**
2207 * if on is true, wait for state become ON
2208 * if off is true, wait for state become OFF
2209 * if both on and off are false, wait for state not ON
2210 */
2211 private boolean waitForOnOff(boolean on, boolean off) {
2212 int i = 0;
2213 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002214 try {
2215 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002216 if (mBluetooth == null) {
2217 break;
2218 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002219 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002220 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2221 return true;
2222 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002223 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002224 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2225 return true;
2226 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002227 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002228 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2229 return true;
2230 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002231 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002232 } catch (RemoteException e) {
2233 Slog.e(TAG, "getState()", e);
2234 break;
2235 } finally {
2236 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002237 }
2238 if (on || off) {
2239 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002240 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002241 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002242 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002243 i++;
2244 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002245 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002246 return false;
2247 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002248
Jack He8caab152018-03-02 13:08:36 -08002249 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002250 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002251 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002252 }
2253
Jack He8caab152018-03-02 13:08:36 -08002254 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002255 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002256 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002257 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002258 }
2259
Jack He8caab152018-03-02 13:08:36 -08002260 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002261 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002262 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002263 mActiveLogs.remove();
2264 }
Jack He8caab152018-03-02 13:08:36 -08002265 mActiveLogs.add(
2266 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002267 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002268
2269 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2270 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2271 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2272 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002273 }
2274
Marie Janssene54b4222017-03-16 18:10:59 -07002275 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002276 synchronized (mCrashTimestamps) {
2277 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2278 mCrashTimestamps.removeFirst();
2279 }
2280 mCrashTimestamps.add(System.currentTimeMillis());
2281 mCrashes++;
2282 }
Marie Janssene54b4222017-03-16 18:10:59 -07002283 }
2284
Marie Janssen2977c3e2016-11-09 12:01:24 -08002285 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002286 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002287 try {
2288 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002289 if (mBluetooth != null) {
2290 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002291 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002292 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002293 } catch (RemoteException re) {
2294 Slog.e(TAG, "Unable to unregister", re);
2295 } finally {
2296 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002297 }
2298
2299 SystemClock.sleep(500);
2300
2301 // disable
Jack He8caab152018-03-02 13:08:36 -08002302 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2303 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002304 handleDisable();
2305
2306 waitForOnOff(false, true);
2307
2308 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002309
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002310 try {
2311 mBluetoothLock.writeLock().lock();
2312 if (mBluetooth != null) {
2313 mBluetooth = null;
2314 // Unbind
2315 mContext.unbindService(mConnection);
2316 }
2317 mBluetoothGatt = null;
2318 } finally {
2319 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002320 }
2321
2322 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2323 mState = BluetoothAdapter.STATE_OFF;
2324
Marie Janssen2977c3e2016-11-09 12:01:24 -08002325 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002326 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002327 }
2328
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002329 mEnable = false;
2330
Ugo Yu1ff6fd32019-11-20 17:59:11 +08002331 // Send a Bluetooth Restart message to reenable bluetooth
2332 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
2333 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002334 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002335
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002336 private boolean isBluetoothDisallowed() {
2337 long callingIdentity = Binder.clearCallingIdentity();
2338 try {
2339 return mContext.getSystemService(UserManager.class)
2340 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2341 } finally {
2342 Binder.restoreCallingIdentity(callingIdentity);
2343 }
2344 }
2345
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002346 /**
2347 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002348 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2349 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002350 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002351 * @param userId user to disable bluetooth sharing for.
2352 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002353 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002354 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002355 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2356 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002357 final int newState =
2358 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2359 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002360 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002361 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002362 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2363 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002364 } catch (Exception e) {
2365 // The component was not found, do nothing.
2366 }
2367 }
2368
Ugo Yu1ff6fd32019-11-20 17:59:11 +08002369 private int getServiceRestartMs() {
2370 return (mErrorRecoveryRetryCounter + 1) * SERVICE_RESTART_TIME_MS;
2371 }
2372
Mike Lockwood726d4de2014-10-28 14:06:28 -07002373 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002374 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002375 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2376 return;
2377 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002378 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002379
2380 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2381
2382 if (!protoOut) {
2383 writer.println("Bluetooth Status");
2384 writer.println(" enabled: " + isEnabled());
2385 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2386 writer.println(" address: " + mAddress);
2387 writer.println(" name: " + mName);
2388 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002389 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002390 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2391 (int) (onDuration / (1000 * 60 * 60)),
2392 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2393 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002394 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002395 }
2396
Marie Janssena95924d2017-01-18 09:37:52 -08002397 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002398 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002399 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002400 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002401 for (ActiveLog log : mActiveLogs) {
2402 writer.println(" " + log);
2403 }
Marie Janssen59804562016-12-28 14:13:21 -08002404 }
2405
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002406 writer.println(
2407 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2408 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2409 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2410 }
Marie Janssene54b4222017-03-16 18:10:59 -07002411 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002412 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002413 }
2414
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002415 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2416 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002417 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002418 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002419 }
2420
Marie Janssena95924d2017-01-18 09:37:52 -08002421 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002422 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002423 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002424 // Add arg to produce output
2425 args = new String[1];
2426 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002427 }
Marie Janssen59804562016-12-28 14:13:21 -08002428 }
2429
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002430 if (mBluetoothBinder == null) {
2431 errorMsg = "Bluetooth Service not connected";
2432 } else {
2433 try {
2434 mBluetoothBinder.dump(fd, args);
2435 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002436 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002437 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002438 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002439 if (errorMsg != null) {
2440 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002441 if (protoOut) {
2442 return;
2443 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002444 writer.println(errorMsg);
2445 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002446 }
Jack He8caab152018-03-02 13:08:36 -08002447
2448 private static String getEnableDisableReasonString(int reason) {
2449 switch (reason) {
2450 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2451 return "APPLICATION_REQUEST";
2452 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2453 return "AIRPLANE_MODE";
2454 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2455 return "DISALLOWED";
2456 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2457 return "RESTARTED";
2458 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2459 return "START_ERROR";
2460 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2461 return "SYSTEM_BOOT";
2462 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2463 return "CRASH";
2464 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2465 return "USER_SWITCH";
2466 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2467 return "RESTORE_USER_SETTING";
2468 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2469 default: return "UNKNOWN[" + reason + "]";
2470 }
2471 }
fredc0f420372012-04-12 00:02:00 -07002472}