blob: 49de4b15777666f9da8128f8f4413be2c224cde3 [file] [log] [blame]
fredc0f420372012-04-12 00:02:00 -07001/*
Zhihai Xufa0fd392012-10-23 17:31:56 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
fredc0f420372012-04-12 00:02:00 -070015 */
16
17package com.android.server;
18
Svet Ganov408abf72015-05-12 19:13:36 -070019import android.Manifest;
Zhihai Xu40874a02012-10-08 17:57:03 -070020import android.app.ActivityManager;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010021import android.app.AppGlobals;
fredc0f420372012-04-12 00:02:00 -070022import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000023import android.bluetooth.BluetoothProfile;
Jack He8caab152018-03-02 13:08:36 -080024import android.bluetooth.BluetoothProtoEnums;
fredc0f420372012-04-12 00:02:00 -070025import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070026import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070027import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000028import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070029import android.bluetooth.IBluetoothManager;
30import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000031import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070032import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070033import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070034import android.content.BroadcastReceiver;
35import android.content.ComponentName;
36import android.content.ContentResolver;
37import android.content.Context;
38import android.content.Intent;
39import android.content.IntentFilter;
40import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070041import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010042import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070043import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000044import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070045import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070046import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010047import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070048import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070049import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070050import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070051import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070052import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070053import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070054import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070055import android.os.SystemClock;
Stanley Tngcbfcbd12018-06-19 08:48:10 -070056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000058import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010059import android.os.UserManagerInternal;
60import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070061import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070062import android.provider.Settings.SettingNotFoundException;
Stanley Tngcbfcbd12018-06-19 08:48:10 -070063import android.text.TextUtils;
64import android.util.FeatureFlagUtils;
65import android.util.Log;
Jeff Sharkey67609c72016-03-05 14:29:13 -070066import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000067import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070068
Arthur Hsuf3f95a92018-01-11 16:46:22 -080069import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060070import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010071import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010072
Mike Lockwood726d4de2014-10-28 14:06:28 -070073import java.io.FileDescriptor;
74import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000075import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080076import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080077import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000078import java.util.Map;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010079import java.util.concurrent.ConcurrentHashMap;
80import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070081
Marie Janssen59804562016-12-28 14:13:21 -080082
fredc0f420372012-04-12 00:02:00 -070083class BluetoothManagerService extends IBluetoothManager.Stub {
84 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070085 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070086
fredc0f420372012-04-12 00:02:00 -070087 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
88 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070089
Myles Watsonb5cd11a2017-11-27 16:42:11 -080090 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
91 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
92 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070093
94 private static final int ACTIVE_LOG_MAX_SIZE = 20;
95 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070096
fredc0f420372012-04-12 00:02:00 -070097 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053098 //Maximum msec to wait for service restart
99 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800100 //Maximum msec to wait for restart due to error
101 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700102 //Maximum msec to delay MESSAGE_USER_SWITCHED
103 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000104 // Delay for the addProxy function in msec
105 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700106
107 private static final int MESSAGE_ENABLE = 1;
108 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700109 private static final int MESSAGE_REGISTER_ADAPTER = 20;
110 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
111 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
112 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
113 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
114 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530115 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700116 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
117 private static final int MESSAGE_TIMEOUT_BIND = 100;
118 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700119 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700120 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700121 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000122 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
123 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700124 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
125
126 private static final int RESTORE_SETTING_TO_ON = 1;
127 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800128
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700129 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800130
Zhihai Xu401202b2012-12-03 11:36:21 -0800131 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800132 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800133 // Bluetooth persisted setting is on
134 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800135 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800136 // Bluetooth persisted setting is on
137 // but Airplane mode will affect Bluetooth state at start up
138 // and Airplane mode will have higher priority.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800139 private static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700140
Matthew Xieddf7e472013-03-01 18:41:02 -0800141 private static final int SERVICE_IBLUETOOTH = 1;
142 private static final int SERVICE_IBLUETOOTHGATT = 2;
143
fredc0f420372012-04-12 00:02:00 -0700144 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700145
146 // Locks are not provided for mName and mAddress.
147 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700148 private String mAddress;
149 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700150 private final ContentResolver mContentResolver;
151 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
152 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800153 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700154 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800155 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800156 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700157 private boolean mBinding;
158 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800159
Zhihai Xu401202b2012-12-03 11:36:21 -0800160 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700161 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800162 private boolean mEnable;
163
Jack He8caab152018-03-02 13:08:36 -0800164 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700165 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
166 }
167
Marie Janssen59804562016-12-28 14:13:21 -0800168 /**
169 * Used for tracking apps that enabled / disabled Bluetooth.
170 */
171 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800172 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800173 private String mPackageName;
174 private boolean mEnable;
175 private long mTimestamp;
176
Jack He8caab152018-03-02 13:08:36 -0800177 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
178 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800179 mPackageName = packageName;
180 mEnable = enable;
181 mTimestamp = timestamp;
182 }
183
Marie Janssen59804562016-12-28 14:13:21 -0800184 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800185 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
186 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800187 }
188
189 }
190
Jack He8caab152018-03-02 13:08:36 -0800191 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
192 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700193 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700194 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800195
196 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800197 // synchronize with broadcast receiver.
198 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800199 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800200
201 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800202 private Map<IBinder, ClientDeathRecipient> mBleApps =
203 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800204
Zhihai Xu40874a02012-10-08 17:57:03 -0700205 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700206 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800207 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200208 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700209
Benjamin Franze8b98922014-11-12 15:57:54 +0000210 // Save a ProfileServiceConnections object for each of the bound
211 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800212 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000213
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700214 private final boolean mPermissionReviewRequired;
215
Marie Janssen59804562016-12-28 14:13:21 -0800216 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700217 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800218 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
219 Message msg =
220 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700221 mHandler.sendMessage(msg);
222 }
223 };
224
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100225 private final UserRestrictionsListener mUserRestrictionsListener =
226 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800227 @Override
228 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
229 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700230
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800231 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
232 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
233 updateOppLauncherComponentState(userId,
234 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
235 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100236
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800237 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
238 if (userId == UserHandle.USER_SYSTEM
239 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
240 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
241 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
242 UserManager.DISALLOW_BLUETOOTH)) {
243 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800244 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
245 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800246 } else {
247 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
248 UserManager.DISALLOW_BLUETOOTH_SHARING));
249 }
250 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100251 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800252 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100253
Ajay Panicker467bc042017-02-22 12:23:15 -0800254 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
255 @Override
256 public void onChange(boolean unused) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800257 synchronized (this) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800258 if (isBluetoothPersistedStateOn()) {
259 if (isAirplaneModeOn()) {
260 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
261 } else {
262 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
263 }
264 }
265
266 int st = BluetoothAdapter.STATE_OFF;
267 try {
268 mBluetoothLock.readLock().lock();
269 if (mBluetooth != null) {
270 st = mBluetooth.getState();
271 }
272 } catch (RemoteException e) {
273 Slog.e(TAG, "Unable to call getState", e);
274 return;
275 } finally {
276 mBluetoothLock.readLock().unlock();
277 }
278
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800279 Slog.d(TAG,
280 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
281 st));
Ajay Panicker467bc042017-02-22 12:23:15 -0800282
283 if (isAirplaneModeOn()) {
284 // Clear registered LE apps to force shut-off
285 clearBleApps();
286
287 // If state is BLE_ON make sure we trigger disableBLE
288 if (st == BluetoothAdapter.STATE_BLE_ON) {
289 try {
290 mBluetoothLock.readLock().lock();
291 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700292 addActiveLog(
293 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
294 mContext.getPackageName(), false);
Ajay Panicker467bc042017-02-22 12:23:15 -0800295 mBluetooth.onBrEdrDown();
296 mEnable = false;
297 mEnableExternal = false;
298 }
299 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800300 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800301 } finally {
302 mBluetoothLock.readLock().unlock();
303 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800304 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800305 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
306 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800307 }
308 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800309 sendEnableMsg(mQuietEnableExternal,
310 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
311 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800312 }
313 }
314 }
315 };
316
fredcbf072a72012-05-09 16:52:50 -0700317 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700318 @Override
319 public void onReceive(Context context, Intent intent) {
320 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700321 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700322 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800323 if (DBG) {
324 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
325 }
fredc0f420372012-04-12 00:02:00 -0700326 if (newName != null) {
327 storeNameAndAddress(newName, null);
328 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700329 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
330 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
331 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800332 if (DBG) {
333 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
334 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700335 storeNameAndAddress(null, newAddress);
336 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800337 if (DBG) {
338 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
339 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700340 }
Stanley Tng873b5702017-05-01 21:27:31 -0700341 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
342 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
343 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
344 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800345 final String prevValue =
346 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
347 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700348
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800349 if (DBG) {
350 Slog.d(TAG,
351 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
352 + ", newValue=" + newValue);
353 }
Stanley Tng873b5702017-05-01 21:27:31 -0700354
355 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
356 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800357 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
358 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700359 mHandler.sendMessage(msg);
360 }
361 }
fredc0f420372012-04-12 00:02:00 -0700362 }
363 }
364 };
365
366 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700367 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700368
fredc0f420372012-04-12 00:02:00 -0700369 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700370
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800371 mPermissionReviewRequired = context.getResources()
372 .getBoolean(com.android.internal.R.bool.config_permissionReviewRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700373
Marie Janssene54b4222017-03-16 18:10:59 -0700374 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700375 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800376 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800377 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700378 mBinding = false;
379 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700380 mEnable = false;
381 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800382 mQuietEnableExternal = false;
383 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700384 mAddress = null;
385 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800386 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700387 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700388 // Observe BLE scan only mode settings change.
389 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700390 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
391 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700392
Stanley Tngcbfcbd12018-06-19 08:48:10 -0700393 // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
394 boolean isHearingAidEnabled;
395 String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
396 if (!TextUtils.isEmpty(value)) {
397 isHearingAidEnabled = Boolean.parseBoolean(value);
398 Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
399 FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
400 }
401
Stanley Tng873b5702017-05-01 21:27:31 -0700402 IntentFilter filter = new IntentFilter();
403 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
404 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
405 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700406 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700407 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700408
fredc0f420372012-04-12 00:02:00 -0700409 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800410 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800411 if (DBG) {
412 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
413 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800414 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700415 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200416
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800417 String airplaneModeRadios =
418 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
419 if (airplaneModeRadios == null || airplaneModeRadios.contains(
420 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800421 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800422 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
423 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800424 }
425
Marie Janssen59804562016-12-28 14:13:21 -0800426 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200427 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800428 // Check if device is configured with no home screen, which implies no SystemUI.
429 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
430 if (!noHome) {
431 systemUiUid = mContext.getPackageManager()
432 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
433 UserHandle.USER_SYSTEM);
434 }
435 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200436 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700437 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700438 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200439 }
Marie Janssen59804562016-12-28 14:13:21 -0800440 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700441 }
442
fredc649fe492012-04-19 01:07:18 -0700443 /**
444 * Returns true if airplane mode is currently on
445 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800446 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700447 return Settings.Global.getInt(mContext.getContentResolver(),
448 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700449 }
450
Arthur Hsu2433baf2018-01-11 11:05:11 -0800451 private boolean supportBluetoothPersistedState() {
452 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
453 }
454
fredc649fe492012-04-19 01:07:18 -0700455 /**
456 * Returns true if the Bluetooth saved state is "on"
457 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800458 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800459 if (!supportBluetoothPersistedState()) {
460 return false;
461 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800462 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
463 if (DBG) {
464 Slog.d(TAG, "Bluetooth persisted state: " + state);
465 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700466 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800467 }
468
469 /**
470 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
471 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800472 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800473 if (!supportBluetoothPersistedState()) {
474 return false;
475 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800476 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
477 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700478 }
479
480 /**
481 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700482 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800483 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800484 if (DBG) {
485 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
486 }
Marie Janssenfa630682016-12-15 13:51:30 -0800487 // waive WRITE_SECURE_SETTINGS permission check
488 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800489 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800490 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700491 }
492
493 /**
494 * Returns true if the Bluetooth Adapter's name and address is
495 * locally cached
496 * @return
497 */
fredc0f420372012-04-12 00:02:00 -0700498 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800499 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700500 }
501
fredc649fe492012-04-19 01:07:18 -0700502 /**
503 * Retrieve the Bluetooth Adapter's name and address and save it in
504 * in the local cache
505 */
fredc0f420372012-04-12 00:02:00 -0700506 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800507 if (DBG) {
508 Slog.d(TAG, "Loading stored name and address");
509 }
510 if (mContext.getResources()
511 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
512 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
513 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700514 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800515 if (DBG) {
516 Slog.d(TAG, "invalid bluetooth name and address stored");
517 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700518 return;
519 }
fredc0f420372012-04-12 00:02:00 -0700520 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
521 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800522 if (DBG) {
523 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
524 }
fredc0f420372012-04-12 00:02:00 -0700525 }
526
fredc649fe492012-04-19 01:07:18 -0700527 /**
528 * Save the Bluetooth name and address in the persistent store.
529 * Only non-null values will be saved.
530 * @param name
531 * @param address
532 */
fredc0f420372012-04-12 00:02:00 -0700533 private void storeNameAndAddress(String name, String address) {
534 if (name != null) {
535 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700536 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800537 if (DBG) {
538 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
539 SECURE_SETTINGS_BLUETOOTH_NAME));
540 }
fredc0f420372012-04-12 00:02:00 -0700541 }
542
543 if (address != null) {
544 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800545 mAddress = address;
546 if (DBG) {
547 Slog.d(TAG,
548 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
549 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
550 }
fredc0f420372012-04-12 00:02:00 -0700551 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700552
553 if ((name != null) && (address != null)) {
554 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
555 }
fredc0f420372012-04-12 00:02:00 -0700556 }
557
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800558 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700559 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700560 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700561 return null;
562 }
fredc0f420372012-04-12 00:02:00 -0700563 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
564 msg.obj = callback;
565 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700566
567 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700568 }
569
570 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700571 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700572 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700573 return;
574 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800575 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700576 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
577 msg.obj = callback;
578 mHandler.sendMessage(msg);
579 }
580
581 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800582 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800583 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800584 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
585 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800586 }
fredc0f420372012-04-12 00:02:00 -0700587 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
588 msg.obj = callback;
589 mHandler.sendMessage(msg);
590 }
591
592 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800593 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800594 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800595 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
596 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800597 }
fredc0f420372012-04-12 00:02:00 -0700598 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
599 msg.obj = callback;
600 mHandler.sendMessage(msg);
601 }
602
603 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800604 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
605 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700606 return false;
607 }
608
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700609 try {
610 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800611 if (mBluetooth != null) {
612 return mBluetooth.isEnabled();
613 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700614 } catch (RemoteException e) {
615 Slog.e(TAG, "isEnabled()", e);
616 } finally {
617 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700618 }
619 return false;
620 }
621
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700622 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800623 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800624 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700625 return BluetoothAdapter.STATE_OFF;
626 }
627
628 try {
629 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800630 if (mBluetooth != null) {
631 return mBluetooth.getState();
632 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700633 } catch (RemoteException e) {
634 Slog.e(TAG, "getState()", e);
635 } finally {
636 mBluetoothLock.readLock().unlock();
637 }
638 return BluetoothAdapter.STATE_OFF;
639 }
640
Nitin Arorad055adb2015-03-02 15:03:51 -0800641 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800642 private String mPackageName;
643
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800644 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800645 mPackageName = packageName;
646 }
647
Nitin Arorad055adb2015-03-02 15:03:51 -0800648 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800649 if (DBG) {
650 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800651 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700652
653 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
654 IBinder token = entry.getKey();
655 ClientDeathRecipient deathRec = entry.getValue();
656 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700657 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700658 break;
659 }
660 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800661 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800662
Marie Janssen59804562016-12-28 14:13:21 -0800663 public String getPackageName() {
664 return mPackageName;
665 }
666 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800667
Wei Wang67d84162015-04-26 17:04:29 -0700668 @Override
669 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700670 if (isAirplaneModeOn() && !mEnable) {
671 return false;
672 }
Wei Wang67d84162015-04-26 17:04:29 -0700673 try {
Jack He8caab152018-03-02 13:08:36 -0800674 return Settings.Global.getInt(mContentResolver,
675 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700676 } catch (SettingNotFoundException e) {
677 }
678 return false;
679 }
680
Wei Wange4a744b2015-06-11 17:50:29 -0700681 // Monitor change of BLE scan only mode settings.
682 private void registerForBleScanModeChange() {
683 ContentObserver contentObserver = new ContentObserver(null) {
684 @Override
685 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800686 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800687 // Nothing to do
688 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800689 }
690 // BLE scan is not available.
691 disableBleScanMode();
692 clearBleApps();
693 try {
694 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800695 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700696 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
697 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800698 mBluetooth.onBrEdrDown();
699 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800700 } catch (RemoteException e) {
701 Slog.e(TAG, "error when disabling bluetooth", e);
702 } finally {
703 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700704 }
705 }
706 };
707
708 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800709 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
710 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700711 }
712
713 // Disable ble scan only mode.
714 private void disableBleScanMode() {
715 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700716 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700717 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800718 if (DBG) {
719 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
720 }
Wei Wange4a744b2015-06-11 17:50:29 -0700721 mEnable = false;
722 }
723 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700724 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700725 } finally {
726 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700727 }
728 }
729
Marie Janssen59804562016-12-28 14:13:21 -0800730 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
731 ClientDeathRecipient r = mBleApps.get(token);
732 if (r == null && enable) {
733 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
734 try {
735 token.linkToDeath(deathRec, 0);
736 } catch (RemoteException ex) {
737 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800738 }
Marie Janssen59804562016-12-28 14:13:21 -0800739 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800740 if (DBG) {
741 Slog.d(TAG, "Registered for death of " + packageName);
742 }
Marie Janssen59804562016-12-28 14:13:21 -0800743 } else if (!enable && r != null) {
744 // Unregister death recipient as the app goes away.
745 token.unlinkToDeath(r, 0);
746 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800747 if (DBG) {
748 Slog.d(TAG, "Unregistered for death of " + packageName);
749 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800750 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800751 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800752 if (DBG) {
753 Slog.d(TAG, appCount + " registered Ble Apps");
754 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800755 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700756 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800757 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800758 if (appCount == 0 && !mEnableExternal) {
759 sendBrEdrDownCallback();
760 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800761 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800762 }
763
Wei Wange4a744b2015-06-11 17:50:29 -0700764 // Clear all apps using BLE scan only mode.
765 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800766 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700767 }
768
Marie Janssen59804562016-12-28 14:13:21 -0800769 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800770 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800771 if (DBG) {
772 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
773 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800774 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800775 }
776
777 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700778 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800779 */
Myles Watson304ebf22018-05-11 08:47:24 -0700780 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800781 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700782 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800783 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700784 try {
785 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800786 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700787 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800788 return;
789 }
790 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
791 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800792 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800793 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800794 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700795 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800796 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700797 } finally {
798 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800799 }
800 }
801
802 /**
803 * Inform BluetoothAdapter instances that BREDR part is down
804 * and turn off all service and stack if no LE app needs it
805 */
806 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800807 if (DBG) {
808 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
809 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700810
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700811 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700812 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700813 return;
814 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800815
Martin Brabhamc2b06222017-02-27 16:55:07 -0800816 if (isBleAppPresent()) {
817 // Need to stay at BLE ON. Disconnect all Gatt connections
818 try {
819 mBluetoothGatt.unregAll();
820 } catch (RemoteException e) {
821 Slog.e(TAG, "Unable to disconnect all apps.", e);
822 }
823 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800824 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700825 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800826 if (mBluetooth != null) {
827 mBluetooth.onBrEdrDown();
828 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700829 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700830 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700831 } finally {
832 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800833 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800834 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800835
Nitin Arorad055adb2015-03-02 15:03:51 -0800836 }
837
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800838 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100839 if (isBluetoothDisallowed()) {
840 if (DBG) {
841 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
842 }
843 return false;
844 }
845
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700846 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800847 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700848
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700849 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800850 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
851 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700852 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800853 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
854
855 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700856 throw new SecurityException("no permission to enable Bluetooth quietly");
857 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800858
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800859 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800860 mQuietEnableExternal = true;
861 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800862 sendEnableMsg(true,
863 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800864 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700865 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700866 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700867
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700868 public boolean enable(String packageName) throws RemoteException {
869 final int callingUid = Binder.getCallingUid();
870 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
871
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100872 if (isBluetoothDisallowed()) {
873 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800874 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100875 }
876 return false;
877 }
878
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700879 if (!callerSystem) {
880 if (!checkIfCallerIsForegroundUser()) {
881 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
882 return false;
883 }
884
885 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
886 "Need BLUETOOTH ADMIN permission");
887
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800888 if (!isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
889 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700890 return false;
891 }
fredcf2458862012-04-16 15:18:27 -0700892 }
893
Zhihai Xu401202b2012-12-03 11:36:21 -0800894 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800895 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
896 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700897 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800898
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800899 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800900 mQuietEnableExternal = false;
901 mEnableExternal = true;
902 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800903 sendEnableMsg(false,
904 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800905 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800906 if (DBG) {
907 Slog.d(TAG, "enable returning");
908 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800909 return true;
fredc0f420372012-04-12 00:02:00 -0700910 }
911
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700912 public boolean disable(String packageName, boolean persist) throws RemoteException {
913 final int callingUid = Binder.getCallingUid();
914 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700915
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700916 if (!callerSystem) {
917 if (!checkIfCallerIsForegroundUser()) {
918 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
919 return false;
920 }
921
922 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
923 "Need BLUETOOTH ADMIN permission");
924
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800925 if (isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
926 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700927 return false;
928 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700929 }
930
fredcf2458862012-04-16 15:18:27 -0700931 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800932 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700933 }
fredcf2458862012-04-16 15:18:27 -0700934
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800935 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800936 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800937 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800938 }
939 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800940 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
941 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800942 }
fredc0f420372012-04-12 00:02:00 -0700943 return true;
944 }
945
baishengf62d8692018-01-25 18:07:24 +0800946 private boolean startConsentUiIfNeeded(String packageName,
947 int callingUid, String intentAction) throws RemoteException {
948 if (checkBluetoothPermissionWhenPermissionReviewRequired()) {
949 return false;
950 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700951 try {
952 // Validate the package only if we are going to use it
953 ApplicationInfo applicationInfo = mContext.getPackageManager()
954 .getApplicationInfoAsUser(packageName,
955 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
956 UserHandle.getUserId(callingUid));
957 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800958 throw new SecurityException("Package " + packageName
959 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700960 }
961
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000962 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000963 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800964 intent.setFlags(
965 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000966 try {
967 mContext.startActivity(intent);
968 } catch (ActivityNotFoundException e) {
969 // Shouldn't happen
970 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
971 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700972 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000973 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700974 } catch (PackageManager.NameNotFoundException e) {
975 throw new RemoteException(e.getMessage());
976 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700977 }
978
baishengf62d8692018-01-25 18:07:24 +0800979 /**
980 * Check if the caller must still pass permission check or if the caller is exempted
981 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED check.
982 *
983 * Commands from some callers may be exempted from triggering the consent UI when
984 * enabling bluetooth. This exemption is checked via the
985 * MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED and allows calls to skip
986 * the consent UI where it may otherwise be required.
987 *
988 * @hide
989 */
990 private boolean checkBluetoothPermissionWhenPermissionReviewRequired() {
991 if (!mPermissionReviewRequired) {
992 return false;
993 }
994 int result = mContext.checkCallingPermission(
995 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED);
996 return result == PackageManager.PERMISSION_GRANTED;
997 }
998
fredc649fe492012-04-19 01:07:18 -0700999 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -07001000 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001001 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
1002 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -07001003 }
1004
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001005 try {
1006 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001007 if (mUnbinding) {
1008 return;
1009 }
fredc0f420372012-04-12 00:02:00 -07001010 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001011 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001012 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001013 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001014 //Unregister callback object
1015 try {
1016 mBluetooth.unregisterCallback(mBluetoothCallback);
1017 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001018 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001019 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001020 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001021 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001022 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001023 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001024 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001025 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001026 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001027 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001028 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001029 } finally {
1030 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001031 }
1032 }
1033
Matthew Xieddf7e472013-03-01 18:41:02 -08001034 public IBluetoothGatt getBluetoothGatt() {
1035 // sync protection
1036 return mBluetoothGatt;
1037 }
1038
Benjamin Franze8b98922014-11-12 15:57:54 +00001039 @Override
1040 public boolean bindBluetoothProfileService(int bluetoothProfile,
1041 IBluetoothProfileServiceConnection proxy) {
1042 if (!mEnable) {
1043 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001044 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1045 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001046 }
1047 return false;
1048 }
1049 synchronized (mProfileServices) {
1050 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1051 if (psc == null) {
1052 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001053 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1054 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001055 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001056
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001057 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1058 return false;
1059 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001060
1061 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001062 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001063 if (!psc.bindService()) {
1064 return false;
1065 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001066
Benjamin Franze8b98922014-11-12 15:57:54 +00001067 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001068 }
1069 }
1070
1071 // Introducing a delay to give the client app time to prepare
1072 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1073 addProxyMsg.arg1 = bluetoothProfile;
1074 addProxyMsg.obj = proxy;
1075 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1076 return true;
1077 }
1078
1079 @Override
1080 public void unbindBluetoothProfileService(int bluetoothProfile,
1081 IBluetoothProfileServiceConnection proxy) {
1082 synchronized (mProfileServices) {
1083 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1084 if (psc == null) {
1085 return;
1086 }
1087 psc.removeProxy(proxy);
1088 }
1089 }
1090
1091 private void unbindAllBluetoothProfileServices() {
1092 synchronized (mProfileServices) {
1093 for (Integer i : mProfileServices.keySet()) {
1094 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001095 try {
1096 mContext.unbindService(psc);
1097 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001098 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001099 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001100 psc.removeAllProxies();
1101 }
1102 mProfileServices.clear();
1103 }
1104 }
1105
1106 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001107 * Send enable message and set adapter name and address. Called when the boot phase becomes
1108 * PHASE_SYSTEM_SERVICES_READY.
1109 */
1110 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001111 if (DBG) {
1112 Slog.d(TAG, "Bluetooth boot completed");
1113 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001114 UserManagerInternal userManagerInternal =
1115 LocalServices.getService(UserManagerInternal.class);
1116 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001117 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001118 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001119 return;
1120 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001121 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001122 if (DBG) {
1123 Slog.d(TAG, "Auto-enabling Bluetooth.");
1124 }
Jack He8caab152018-03-02 13:08:36 -08001125 sendEnableMsg(mQuietEnableExternal,
1126 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1127 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001128 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001129 if (DBG) {
1130 Slog.d(TAG, "Getting adapter name and address");
1131 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001132 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1133 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001134 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001135 }
1136
1137 /**
1138 * Called when switching to a different foreground user.
1139 */
1140 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001141 if (DBG) {
1142 Slog.d(TAG, "User " + userHandle + " switched");
1143 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001144 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1145 }
1146
1147 /**
1148 * Called when user is unlocked.
1149 */
1150 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001151 if (DBG) {
1152 Slog.d(TAG, "User " + userHandle + " unlocked");
1153 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001154 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001155 }
1156
1157 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001158 * This class manages the clients connected to a given ProfileService
1159 * and maintains the connection with that service.
1160 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001161 private final class ProfileServiceConnections
1162 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001163 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001164 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001165 IBinder mService;
1166 ComponentName mClassName;
1167 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001168 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001169
1170 ProfileServiceConnections(Intent intent) {
1171 mService = null;
1172 mClassName = null;
1173 mIntent = intent;
1174 }
1175
Benjamin Franz5b614592014-12-09 18:58:45 +00001176 private boolean bindService() {
jonerlin37fc85d2018-08-09 16:39:43 +08001177 int state = BluetoothAdapter.STATE_OFF;
1178 try {
1179 mBluetoothLock.readLock().lock();
1180 if (mBluetooth != null) {
1181 state = mBluetooth.getState();
1182 }
1183 } catch (RemoteException e) {
1184 Slog.e(TAG, "Unable to call getState", e);
1185 return false;
1186 } finally {
1187 mBluetoothLock.readLock().unlock();
1188 }
1189
1190 if (!mEnable || state != BluetoothAdapter.STATE_ON) {
1191 if (DBG) {
1192 Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
1193 }
1194 return false;
1195 }
1196
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001197 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1198 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001199 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1200 msg.obj = this;
1201 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001202 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001203 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001204 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001205 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001206 }
1207
1208 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1209 mProxies.register(proxy);
1210 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001211 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001212 proxy.onServiceConnected(mClassName, mService);
1213 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001214 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001215 }
1216 } else {
1217 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1218 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1219 msg.obj = this;
1220 mHandler.sendMessage(msg);
1221 }
1222 }
1223 }
1224
1225 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1226 if (proxy != null) {
1227 if (mProxies.unregister(proxy)) {
1228 try {
1229 proxy.onServiceDisconnected(mClassName);
1230 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001231 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001232 }
1233 }
1234 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001235 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001236 }
1237 }
1238
1239 private void removeAllProxies() {
1240 onServiceDisconnected(mClassName);
1241 mProxies.kill();
1242 }
1243
1244 @Override
1245 public void onServiceConnected(ComponentName className, IBinder service) {
1246 // remove timeout message
1247 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1248 mService = service;
1249 mClassName = className;
1250 try {
1251 mService.linkToDeath(this, 0);
1252 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001253 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001254 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001255
1256 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001257 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001258 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001259 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001260 mInvokingProxyCallbacks = true;
1261
1262 final int n = mProxies.beginBroadcast();
1263 try {
1264 for (int i = 0; i < n; i++) {
1265 try {
1266 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1267 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001268 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001269 }
1270 }
1271 } finally {
1272 mProxies.finishBroadcast();
1273 mInvokingProxyCallbacks = false;
1274 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001275 }
1276
1277 @Override
1278 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001279 if (mService == null) {
1280 return;
1281 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001282 mService.unlinkToDeath(this, 0);
1283 mService = null;
1284 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001285
1286 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001287 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001288 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001289 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001290 mInvokingProxyCallbacks = true;
1291
1292 final int n = mProxies.beginBroadcast();
1293 try {
1294 for (int i = 0; i < n; i++) {
1295 try {
1296 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1297 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001298 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001299 }
1300 }
1301 } finally {
1302 mProxies.finishBroadcast();
1303 mInvokingProxyCallbacks = false;
1304 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001305 }
1306
1307 @Override
1308 public void binderDied() {
1309 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001310 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001311 }
1312 onServiceDisconnected(mClassName);
1313 // Trigger rebind
1314 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1315 msg.obj = this;
1316 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1317 }
1318 }
1319
fredcbf072a72012-05-09 16:52:50 -07001320 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001321 try {
1322 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001323 if (DBG) {
1324 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1325 + " receivers.");
1326 }
1327 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001328 try {
1329 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1330 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001331 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001332 }
fredcbf072a72012-05-09 16:52:50 -07001333 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001334 } finally {
1335 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001336 }
fredcbf072a72012-05-09 16:52:50 -07001337 }
1338
1339 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001340 * Inform BluetoothAdapter instances that Adapter service is up
1341 */
1342 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001343 try {
1344 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001345 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1346 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001347 try {
1348 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001349 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001350 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001351 }
1352 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001353 } finally {
1354 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001355 }
1356 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001357
Zhihai Xu40874a02012-10-08 17:57:03 -07001358 /**
fredcbf072a72012-05-09 16:52:50 -07001359 * Inform BluetoothAdapter instances that Adapter service is down
1360 */
1361 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001362 try {
1363 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001364 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1365 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001366 try {
1367 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001368 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001369 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001370 }
1371 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001372 } finally {
1373 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001374 }
1375 }
Svet Ganov408abf72015-05-12 19:13:36 -07001376
fredc0f420372012-04-12 00:02:00 -07001377 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001378 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001379
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001380 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1381 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001382 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001383 }
1384
Svet Ganov408abf72015-05-12 19:13:36 -07001385 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1386 != PackageManager.PERMISSION_GRANTED) {
1387 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1388 }
1389
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001390 try {
1391 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001392 if (mBluetooth != null) {
1393 return mBluetooth.getAddress();
1394 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001395 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001396 Slog.e(TAG,
1397 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1398 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001399 } finally {
1400 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001401 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001402
Matthew Xiecdce0b92012-07-12 19:06:15 -07001403 // mAddress is accessed from outside.
1404 // It is alright without a lock. Here, bluetooth is off, no other thread is
1405 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001406 return mAddress;
1407 }
fredc649fe492012-04-19 01:07:18 -07001408
fredc0f420372012-04-12 00:02:00 -07001409 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001410 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001411
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001412 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1413 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001414 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001415 }
1416
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001417 try {
1418 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001419 if (mBluetooth != null) {
1420 return mBluetooth.getName();
1421 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001422 } catch (RemoteException e) {
1423 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1424 } finally {
1425 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001426 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001427
Matthew Xiecdce0b92012-07-12 19:06:15 -07001428 // mName is accessed from outside.
1429 // It alright without a lock. Here, bluetooth is off, no other thread is
1430 // changing mName
fredc0f420372012-04-12 00:02:00 -07001431 return mName;
1432 }
1433
fredc0f420372012-04-12 00:02:00 -07001434 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001435 public void onServiceConnected(ComponentName componentName, IBinder service) {
1436 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001437 if (DBG) {
1438 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1439 }
fredc0f420372012-04-12 00:02:00 -07001440 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001441 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001442 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001443 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001444 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1445 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001446 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001447 return;
1448 }
fredc0f420372012-04-12 00:02:00 -07001449 msg.obj = service;
1450 mHandler.sendMessage(msg);
1451 }
1452
Marie Janssencb21ad72016-12-13 10:51:02 -08001453 public void onServiceDisconnected(ComponentName componentName) {
1454 // Called if we unexpectedly disconnect.
1455 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001456 if (DBG) {
1457 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1458 }
fredc0f420372012-04-12 00:02:00 -07001459 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001460 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001461 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001462 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001463 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1464 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001465 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001466 return;
1467 }
fredc0f420372012-04-12 00:02:00 -07001468 mHandler.sendMessage(msg);
1469 }
1470 }
1471
1472 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1473
Zhihai Xu40874a02012-10-08 17:57:03 -07001474 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001475 boolean mGetNameAddressOnly = false;
1476
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001477 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001478 super(looper);
1479 }
1480
fredc0f420372012-04-12 00:02:00 -07001481 @Override
1482 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001483 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001484 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001485 if (DBG) {
1486 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1487 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001488 try {
1489 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001490 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001491 if (DBG) {
1492 Slog.d(TAG, "Binding to service to get name and address");
1493 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001494 mGetNameAddressOnly = true;
1495 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1496 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1497 Intent i = new Intent(IBluetooth.class.getName());
1498 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001499 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1500 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001501 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1502 } else {
1503 mBinding = true;
1504 }
1505 } else if (mBluetooth != null) {
1506 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001507 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001508 } catch (RemoteException re) {
1509 Slog.e(TAG, "Unable to grab names", re);
1510 }
1511 if (mGetNameAddressOnly && !mEnable) {
1512 unbindAndFinish();
1513 }
1514 mGetNameAddressOnly = false;
1515 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001516 } finally {
1517 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001518 }
1519 break;
1520
Matthew Xiecdce0b92012-07-12 19:06:15 -07001521 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001522 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001523 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001524 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001525 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1526 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001527
1528 // Use service interface to get the exact state
1529 try {
1530 mBluetoothLock.readLock().lock();
1531 if (mBluetooth != null) {
1532 int state = mBluetooth.getState();
1533 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001534 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001535 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001536 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001537 break;
1538 }
1539 }
1540 } catch (RemoteException e) {
1541 Slog.e(TAG, "", e);
1542 } finally {
1543 mBluetoothLock.readLock().unlock();
1544 }
1545
1546 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001547 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001548 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001549 } else {
1550 //
1551 // We need to wait until transitioned to STATE_OFF and
1552 // the previous Bluetooth process has exited. The
1553 // waiting period has three components:
1554 // (a) Wait until the local state is STATE_OFF. This
1555 // is accomplished by "waitForOnOff(false, true)".
1556 // (b) Wait until the STATE_OFF state is updated to
1557 // all components.
1558 // (c) Wait until the Bluetooth process exits, and
1559 // ActivityManager detects it.
1560 // The waiting for (b) and (c) is accomplished by
1561 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1562 // message. On slower devices, that delay needs to be
1563 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1564 //
1565 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001566 Message restartMsg =
1567 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1568 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001569 }
fredc649fe492012-04-19 01:07:18 -07001570 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001571
fredc0f420372012-04-12 00:02:00 -07001572 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001573 if (DBG) {
1574 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1575 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001576 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1577 if (mEnable && mBluetooth != null) {
1578 waitForOnOff(true, false);
1579 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001580 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001581 waitForOnOff(false, false);
1582 } else {
1583 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001584 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001585 }
fredc0f420372012-04-12 00:02:00 -07001586 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001587
Stanley Tng873b5702017-05-01 21:27:31 -07001588 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001589 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1590 if (DBG) {
1591 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001592 }
Jack He8caab152018-03-02 13:08:36 -08001593 persistBluetoothSetting(BLUETOOTH_OFF);
1594 mEnableExternal = false;
1595 sendDisableMsg(
1596 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1597 mContext.getPackageName());
1598 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1599 if (DBG) {
1600 Slog.d(TAG, "Restore Bluetooth state to enabled");
1601 }
1602 mQuietEnableExternal = false;
1603 mEnableExternal = true;
1604 // waive WRITE_SECURE_SETTINGS permission check
1605 sendEnableMsg(false,
1606 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1607 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001608 }
1609 break;
1610
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001611 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001612 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001613 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001614 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001615 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001616 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001617 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001618 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001619 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001620 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001621 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1622 IBluetoothStateChangeCallback callback =
1623 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001624 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001625 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001626 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001627 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1628 IBluetoothStateChangeCallback callback =
1629 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001630 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001631 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001632 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001633 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001634 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001635 if (psc == null) {
1636 break;
1637 }
1638 IBluetoothProfileServiceConnection proxy =
1639 (IBluetoothProfileServiceConnection) msg.obj;
1640 psc.addProxy(proxy);
1641 break;
1642 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001643 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001644 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1645 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1646 if (psc == null) {
1647 break;
1648 }
1649 psc.bindService();
1650 break;
1651 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001652 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1653 if (DBG) {
1654 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1655 }
fredc0f420372012-04-12 00:02:00 -07001656
1657 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001658 try {
1659 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001660 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001661 mBluetoothGatt =
1662 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001663 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001664 break;
1665 } // else must be SERVICE_IBLUETOOTH
1666
1667 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001668 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001669
fredc0f420372012-04-12 00:02:00 -07001670 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001671 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001672 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001673
Ajay Panicker4bb48302016-03-31 14:14:27 -07001674 if (!isNameAndAddressSet()) {
1675 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1676 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001677 if (mGetNameAddressOnly) {
1678 return;
1679 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001680 }
1681
Matthew Xiecdce0b92012-07-12 19:06:15 -07001682 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001683 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001684 mBluetooth.registerCallback(mBluetoothCallback);
1685 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001686 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001687 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001688 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001689 sendBluetoothServiceUpCallback();
1690
Matthew Xiecdce0b92012-07-12 19:06:15 -07001691 //Do enable request
1692 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001693 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001694 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001695 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001696 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001697 } else {
1698 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001699 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001700 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001701 }
1702 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001703 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001704 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001705 } finally {
1706 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001707 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001708
1709 if (!mEnable) {
1710 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001711 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001712 waitForOnOff(false, false);
1713 }
fredc649fe492012-04-19 01:07:18 -07001714 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001715 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001716 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001717 int prevState = msg.arg1;
1718 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001719 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001720 Slog.d(TAG,
1721 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1722 prevState) + " > " + BluetoothAdapter.nameForState(
1723 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001724 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001725 mState = newState;
1726 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001727 // handle error state transition case from TURNING_ON to OFF
1728 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001729 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1730 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001731 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001732 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001733 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1734 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001735 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001736 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001737 // If we tried to enable BT while BT was in the process of shutting down,
1738 // wait for the BT process to fully tear down and then force a restart
1739 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001740 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1741 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001742 if (mEnable) {
1743 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1744 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001745 Message restartMsg =
1746 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001747 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1748 }
1749 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001750 if (newState == BluetoothAdapter.STATE_ON
1751 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001752 // bluetooth is working, reset the counter
1753 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001754 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001755 mErrorRecoveryRetryCounter = 0;
1756 }
1757 }
fredc649fe492012-04-19 01:07:18 -07001758 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001759 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001760 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001761 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001762 try {
1763 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001764 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1765 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001766 if (mBluetooth == null) {
1767 break;
1768 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001769 mBluetooth = null;
1770 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1771 mBluetoothGatt = null;
1772 break;
1773 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001774 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001775 break;
1776 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001777 } finally {
1778 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301779 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001780
Marie Janssene54b4222017-03-16 18:10:59 -07001781 // log the unexpected crash
1782 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001783 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1784 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001785 if (mEnable) {
1786 mEnable = false;
1787 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001788 Message restartMsg =
1789 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1790 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001791 }
1792
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001793 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001794
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001795 // Send BT state broadcast to update
1796 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001797 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1798 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001799 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001800 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001801 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001802 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001803 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1804 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001805 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001806 }
1807
1808 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1809 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001810 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001811 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001812 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001813 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301814 /* Enable without persisting the setting as
1815 it doesnt change when IBluetooth
1816 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001817 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001818 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1819 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001820 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301821 break;
1822 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001823 case MESSAGE_TIMEOUT_BIND: {
1824 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1825 mBluetoothLock.writeLock().lock();
1826 mBinding = false;
1827 mBluetoothLock.writeLock().unlock();
1828 break;
1829 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001830 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001831 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001832 mBluetoothLock.writeLock().lock();
1833 mUnbinding = false;
1834 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001835 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001836 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001837
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001838 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001839 if (DBG) {
1840 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1841 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001842 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001843
Zhihai Xu40874a02012-10-08 17:57:03 -07001844 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001845 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001846 try {
1847 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001848 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001849 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001850 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001851 } catch (RemoteException re) {
1852 Slog.e(TAG, "Unable to unregister", re);
1853 } finally {
1854 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001855 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001856
1857 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1858 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1859 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1860 mState = BluetoothAdapter.STATE_OFF;
1861 }
1862 if (mState == BluetoothAdapter.STATE_OFF) {
1863 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1864 mState = BluetoothAdapter.STATE_TURNING_ON;
1865 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001866
1867 waitForOnOff(true, false);
1868
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001869 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1870 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1871 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001872
Benjamin Franze8b98922014-11-12 15:57:54 +00001873 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001874 // disable
Jack He8caab152018-03-02 13:08:36 -08001875 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1876 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001877 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001878 // Pbap service need receive STATE_TURNING_OFF intent to close
1879 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001880 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001881
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001882 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001883
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001884 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001885 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001886 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001887
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001888 try {
1889 mBluetoothLock.writeLock().lock();
1890 if (mBluetooth != null) {
1891 mBluetooth = null;
1892 // Unbind
1893 mContext.unbindService(mConnection);
1894 }
1895 mBluetoothGatt = null;
1896 } finally {
1897 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001898 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001899
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001900 //
1901 // If disabling Bluetooth times out, wait for an
1902 // additional amount of time to ensure the process is
1903 // shut down completely before attempting to restart.
1904 //
1905 if (didDisableTimeout) {
1906 SystemClock.sleep(3000);
1907 } else {
1908 SystemClock.sleep(100);
1909 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001910
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001911 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1912 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001913 // enable
Jack He8caab152018-03-02 13:08:36 -08001914 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1915 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001916 // mEnable flag could have been reset on disableBLE. Reenable it.
1917 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001918 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001919 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001920 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1921 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001922 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001923 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1924 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001925 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001926 }
John Spurlock8a985d22014-02-25 09:40:05 -05001927 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001928 break;
1929 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001930 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001931 if (DBG) {
1932 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1933 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001934 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1935
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001936 if (mEnable && !mBinding && (mBluetooth == null)) {
1937 // We should be connected, but we gave up for some
1938 // reason; maybe the Bluetooth service wasn't encryption
1939 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001940 if (DBG) {
1941 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1942 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001943 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001944 }
1945 }
fredc0f420372012-04-12 00:02:00 -07001946 }
1947 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001948 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001949
Zhihai Xu401202b2012-12-03 11:36:21 -08001950 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001951 mQuietEnable = quietMode;
1952
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001953 try {
1954 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001955 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001956 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001957 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1958 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001959 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001960 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001961 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001962 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001963 } else {
1964 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001965 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001966 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001967 //Enable bluetooth
1968 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001969 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001970 if (!mBluetooth.enable()) {
1971 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001972 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001973 } else {
1974 if (!mBluetooth.enableNoAutoConnect()) {
1975 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001976 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001977 }
1978 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001979 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001980 }
1981 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001982 } finally {
1983 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001984 }
1985 }
1986
Dianne Hackborn221ea892013-08-04 16:50:16 -07001987 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1988 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1989 intent.setComponent(comp);
1990 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001991 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001992 return false;
1993 }
1994 return true;
1995 }
1996
Zhihai Xu401202b2012-12-03 11:36:21 -08001997 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001998 try {
1999 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08002000 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002001 if (DBG) {
2002 Slog.d(TAG, "Sending off request.");
2003 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002004 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002005 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002006 }
2007 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002008 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002009 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002010 } finally {
2011 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002012 }
2013 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002014
2015 private boolean checkIfCallerIsForegroundUser() {
2016 int foregroundUser;
2017 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002018 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07002019 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00002020 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
2021 UserInfo ui = um.getProfileParent(callingUser);
2022 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002023 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07002024 boolean valid = false;
2025 try {
2026 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002027 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2028 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002029 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002030 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2031 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2032 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002033 }
2034 } finally {
2035 Binder.restoreCallingIdentity(callingIdentity);
2036 }
2037 return valid;
2038 }
2039
Nitin Arorad055adb2015-03-02 15:03:51 -08002040 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002041 if (DBG) {
2042 Slog.d(TAG,
2043 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2044 + BluetoothAdapter.nameForState(newState));
2045 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002046 // Send broadcast message to everyone else
2047 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2048 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2049 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2051 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2052 }
2053
Zhihai Xu40874a02012-10-08 17:57:03 -07002054 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002055 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002056 if (prevState == newState) { // No change. Nothing to do.
2057 return;
2058 }
2059 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002060 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002061 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002062 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002063
Marie Janssencb21ad72016-12-13 10:51:02 -08002064 if (newState == BluetoothAdapter.STATE_OFF) {
2065 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002066 if (DBG) {
2067 Slog.d(TAG, "Bluetooth is complete send Service Down");
2068 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002069 sendBluetoothServiceDownCallback();
2070 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002071 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002072 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002073 isStandardBroadcast = false;
2074
Marie Janssencb21ad72016-12-13 10:51:02 -08002075 } else if (!intermediate_off) {
2076 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002077 if (DBG) {
2078 Slog.d(TAG, "Bluetooth is in LE only mode");
2079 }
Myles Watson304ebf22018-05-11 08:47:24 -07002080 if (mBluetoothGatt != null || !mContext.getPackageManager()
2081 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2082 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002083 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002084 if (DBG) {
2085 Slog.d(TAG, "Binding Bluetooth GATT service");
2086 }
Myles Watson304ebf22018-05-11 08:47:24 -07002087 Intent i = new Intent(IBluetoothGatt.class.getName());
2088 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2089 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002090 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002091 sendBleStateChanged(prevState, newState);
2092 //Don't broadcase this as std intent
2093 isStandardBroadcast = false;
2094
2095 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002096 if (DBG) {
2097 Slog.d(TAG, "Intermediate off, back to LE only mode");
2098 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002099 // For LE only mode, broadcast as is
2100 sendBleStateChanged(prevState, newState);
2101 sendBluetoothStateCallback(false); // BT is OFF for general users
2102 // Broadcast as STATE_OFF
2103 newState = BluetoothAdapter.STATE_OFF;
2104 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002105 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002106 } else if (newState == BluetoothAdapter.STATE_ON) {
2107 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2108 sendBluetoothStateCallback(isUp);
2109 sendBleStateChanged(prevState, newState);
2110
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002111 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2112 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002113 sendBleStateChanged(prevState, newState);
2114 isStandardBroadcast = false;
2115
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002116 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2117 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002118 sendBleStateChanged(prevState, newState);
2119 }
2120
2121 if (isStandardBroadcast) {
2122 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2123 // Show prevState of BLE_ON as OFF to standard users
2124 prevState = BluetoothAdapter.STATE_OFF;
2125 }
2126 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2127 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2128 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2129 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2130 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002131 }
2132 }
2133
2134 /**
2135 * if on is true, wait for state become ON
2136 * if off is true, wait for state become OFF
2137 * if both on and off are false, wait for state not ON
2138 */
2139 private boolean waitForOnOff(boolean on, boolean off) {
2140 int i = 0;
2141 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002142 try {
2143 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002144 if (mBluetooth == null) {
2145 break;
2146 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002147 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002148 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2149 return true;
2150 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002151 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002152 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2153 return true;
2154 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002155 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002156 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2157 return true;
2158 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002159 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002160 } catch (RemoteException e) {
2161 Slog.e(TAG, "getState()", e);
2162 break;
2163 } finally {
2164 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002165 }
2166 if (on || off) {
2167 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002168 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002169 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002170 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002171 i++;
2172 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002173 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002174 return false;
2175 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002176
Jack He8caab152018-03-02 13:08:36 -08002177 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002178 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002179 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002180 }
2181
Jack He8caab152018-03-02 13:08:36 -08002182 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002183 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002184 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002185 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002186 }
2187
Jack He8caab152018-03-02 13:08:36 -08002188 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002189 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002190 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002191 mActiveLogs.remove();
2192 }
Jack He8caab152018-03-02 13:08:36 -08002193 mActiveLogs.add(
2194 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002195 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002196
2197 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2198 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2199 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2200 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002201 }
2202
Marie Janssene54b4222017-03-16 18:10:59 -07002203 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002204 synchronized (mCrashTimestamps) {
2205 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2206 mCrashTimestamps.removeFirst();
2207 }
2208 mCrashTimestamps.add(System.currentTimeMillis());
2209 mCrashes++;
2210 }
Marie Janssene54b4222017-03-16 18:10:59 -07002211 }
2212
Marie Janssen2977c3e2016-11-09 12:01:24 -08002213 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002214 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002215 try {
2216 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002217 if (mBluetooth != null) {
2218 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002219 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002220 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002221 } catch (RemoteException re) {
2222 Slog.e(TAG, "Unable to unregister", re);
2223 } finally {
2224 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002225 }
2226
2227 SystemClock.sleep(500);
2228
2229 // disable
Jack He8caab152018-03-02 13:08:36 -08002230 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2231 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002232 handleDisable();
2233
2234 waitForOnOff(false, true);
2235
2236 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002237
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002238 try {
2239 mBluetoothLock.writeLock().lock();
2240 if (mBluetooth != null) {
2241 mBluetooth = null;
2242 // Unbind
2243 mContext.unbindService(mConnection);
2244 }
2245 mBluetoothGatt = null;
2246 } finally {
2247 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002248 }
2249
2250 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2251 mState = BluetoothAdapter.STATE_OFF;
2252
Marie Janssen2977c3e2016-11-09 12:01:24 -08002253 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002254 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002255 }
2256
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002257 mEnable = false;
2258
2259 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2260 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002261 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002262 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2263 } else {
2264 // todo: notify user to power down and power up phone to make bluetooth work.
2265 }
2266 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002267
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002268 private boolean isBluetoothDisallowed() {
2269 long callingIdentity = Binder.clearCallingIdentity();
2270 try {
2271 return mContext.getSystemService(UserManager.class)
2272 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2273 } finally {
2274 Binder.restoreCallingIdentity(callingIdentity);
2275 }
2276 }
2277
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002278 /**
2279 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002280 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2281 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002282 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002283 * @param userId user to disable bluetooth sharing for.
2284 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002285 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002286 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002287 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2288 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002289 final int newState =
2290 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2291 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002292 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002293 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002294 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2295 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002296 } catch (Exception e) {
2297 // The component was not found, do nothing.
2298 }
2299 }
2300
Mike Lockwood726d4de2014-10-28 14:06:28 -07002301 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002302 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002303 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2304 return;
2305 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002306 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002307
2308 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2309
2310 if (!protoOut) {
2311 writer.println("Bluetooth Status");
2312 writer.println(" enabled: " + isEnabled());
2313 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2314 writer.println(" address: " + mAddress);
2315 writer.println(" name: " + mName);
2316 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002317 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002318 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2319 (int) (onDuration / (1000 * 60 * 60)),
2320 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2321 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002322 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002323 }
2324
Marie Janssena95924d2017-01-18 09:37:52 -08002325 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002326 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002327 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002328 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002329 for (ActiveLog log : mActiveLogs) {
2330 writer.println(" " + log);
2331 }
Marie Janssen59804562016-12-28 14:13:21 -08002332 }
2333
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002334 writer.println(
2335 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2336 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2337 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2338 }
Marie Janssene54b4222017-03-16 18:10:59 -07002339 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002340 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002341 }
2342
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002343 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2344 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002345 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002346 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002347 }
2348
Marie Janssena95924d2017-01-18 09:37:52 -08002349 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002350 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002351 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002352 // Add arg to produce output
2353 args = new String[1];
2354 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002355 }
Marie Janssen59804562016-12-28 14:13:21 -08002356 }
2357
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002358 if (mBluetoothBinder == null) {
2359 errorMsg = "Bluetooth Service not connected";
2360 } else {
2361 try {
2362 mBluetoothBinder.dump(fd, args);
2363 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002364 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002365 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002366 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002367 if (errorMsg != null) {
2368 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002369 if (protoOut) {
2370 return;
2371 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002372 writer.println(errorMsg);
2373 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002374 }
Jack He8caab152018-03-02 13:08:36 -08002375
2376 private static String getEnableDisableReasonString(int reason) {
2377 switch (reason) {
2378 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2379 return "APPLICATION_REQUEST";
2380 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2381 return "AIRPLANE_MODE";
2382 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2383 return "DISALLOWED";
2384 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2385 return "RESTARTED";
2386 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2387 return "START_ERROR";
2388 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2389 return "SYSTEM_BOOT";
2390 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2391 return "CRASH";
2392 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2393 return "USER_SWITCH";
2394 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2395 return "RESTORE_USER_SETTING";
2396 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2397 default: return "UNKNOWN[" + reason + "]";
2398 }
2399 }
fredc0f420372012-04-12 00:02:00 -07002400}