blob: 7bbc543a6aabeeb86eedb832c2bd9bf0c5fe2ab0 [file] [log] [blame]
fredc0f420372012-04-12 00:02:00 -07001/*
Zhihai Xufa0fd392012-10-23 17:31:56 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
fredc0f420372012-04-12 00:02:00 -070015 */
16
17package com.android.server;
18
Svet Ganov408abf72015-05-12 19:13:36 -070019import android.Manifest;
Zhihai Xu40874a02012-10-08 17:57:03 -070020import android.app.ActivityManager;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010021import android.app.AppGlobals;
fredc0f420372012-04-12 00:02:00 -070022import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000023import android.bluetooth.BluetoothProfile;
Jack He8caab152018-03-02 13:08:36 -080024import android.bluetooth.BluetoothProtoEnums;
fredc0f420372012-04-12 00:02:00 -070025import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070026import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070027import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000028import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070029import android.bluetooth.IBluetoothManager;
30import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000031import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070032import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070033import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070034import android.content.BroadcastReceiver;
35import android.content.ComponentName;
36import android.content.ContentResolver;
37import android.content.Context;
38import android.content.Intent;
39import android.content.IntentFilter;
40import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070041import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010042import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070043import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000044import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070045import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070046import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010047import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070048import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070049import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070050import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070051import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070052import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070053import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070054import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070055import android.os.SystemClock;
Stanley Tngfe8c8332018-06-19 08:48:10 -070056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000058import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010059import android.os.UserManagerInternal;
60import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070061import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070062import android.provider.Settings.SettingNotFoundException;
Stanley Tngfe8c8332018-06-19 08:48:10 -070063import android.text.TextUtils;
64import android.util.FeatureFlagUtils;
65import android.util.Log;
Jeff Sharkey67609c72016-03-05 14:29:13 -070066import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000067import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070068
Arthur Hsuf3f95a92018-01-11 16:46:22 -080069import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060070import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010071import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010072
Mike Lockwood726d4de2014-10-28 14:06:28 -070073import java.io.FileDescriptor;
74import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000075import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080076import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080077import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000078import java.util.Map;
Chienyuan177156b2018-12-18 10:40:25 +080079import java.util.NoSuchElementException;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010080import java.util.concurrent.ConcurrentHashMap;
81import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070082
Marie Janssen59804562016-12-28 14:13:21 -080083
fredc0f420372012-04-12 00:02:00 -070084class BluetoothManagerService extends IBluetoothManager.Stub {
85 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070086 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070087
fredc0f420372012-04-12 00:02:00 -070088 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
89 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070090
Myles Watsonb5cd11a2017-11-27 16:42:11 -080091 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
92 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
93 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070094
95 private static final int ACTIVE_LOG_MAX_SIZE = 20;
96 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070097
fredc0f420372012-04-12 00:02:00 -070098 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053099 //Maximum msec to wait for service restart
100 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800101 //Maximum msec to wait for restart due to error
102 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700103 //Maximum msec to delay MESSAGE_USER_SWITCHED
104 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000105 // Delay for the addProxy function in msec
106 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700107
108 private static final int MESSAGE_ENABLE = 1;
109 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700110 private static final int MESSAGE_REGISTER_ADAPTER = 20;
111 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
112 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
113 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
114 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
115 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530116 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700117 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
118 private static final int MESSAGE_TIMEOUT_BIND = 100;
119 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700120 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700121 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700122 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000123 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
124 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700125 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
126
127 private static final int RESTORE_SETTING_TO_ON = 1;
128 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800129
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700130 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800131
Zhihai Xu401202b2012-12-03 11:36:21 -0800132 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800133 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800134 // Bluetooth persisted setting is on
135 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800136 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800137 // Bluetooth persisted setting is on
138 // but Airplane mode will affect Bluetooth state at start up
139 // and Airplane mode will have higher priority.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800140 private static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700141
Matthew Xieddf7e472013-03-01 18:41:02 -0800142 private static final int SERVICE_IBLUETOOTH = 1;
143 private static final int SERVICE_IBLUETOOTHGATT = 2;
144
fredc0f420372012-04-12 00:02:00 -0700145 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700146
147 // Locks are not provided for mName and mAddress.
148 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700149 private String mAddress;
150 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700151 private final ContentResolver mContentResolver;
152 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
153 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800154 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700155 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800156 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800157 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700158 private boolean mBinding;
159 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800160
Zhihai Xu401202b2012-12-03 11:36:21 -0800161 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700162 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800163 private boolean mEnable;
164
Jack He8caab152018-03-02 13:08:36 -0800165 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700166 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
167 }
168
Marie Janssen59804562016-12-28 14:13:21 -0800169 /**
170 * Used for tracking apps that enabled / disabled Bluetooth.
171 */
172 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800173 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800174 private String mPackageName;
175 private boolean mEnable;
176 private long mTimestamp;
177
Jack He8caab152018-03-02 13:08:36 -0800178 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
179 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800180 mPackageName = packageName;
181 mEnable = enable;
182 mTimestamp = timestamp;
183 }
184
Marie Janssen59804562016-12-28 14:13:21 -0800185 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800186 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
187 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800188 }
189
190 }
191
Jack He8caab152018-03-02 13:08:36 -0800192 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
193 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700194 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700195 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800196
197 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800198 // synchronize with broadcast receiver.
199 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800200 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800201
202 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800203 private Map<IBinder, ClientDeathRecipient> mBleApps =
204 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800205
Zhihai Xu40874a02012-10-08 17:57:03 -0700206 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700207 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800208 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200209 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700210
Benjamin Franze8b98922014-11-12 15:57:54 +0000211 // Save a ProfileServiceConnections object for each of the bound
212 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800213 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000214
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700215 private final boolean mWirelessConsentRequired;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700216
Marie Janssen59804562016-12-28 14:13:21 -0800217 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700218 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800219 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
220 Message msg =
221 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700222 mHandler.sendMessage(msg);
223 }
224 };
225
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100226 private final UserRestrictionsListener mUserRestrictionsListener =
227 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800228 @Override
229 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
230 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700231
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800232 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
233 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
234 updateOppLauncherComponentState(userId,
235 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
236 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100237
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800238 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
239 if (userId == UserHandle.USER_SYSTEM
240 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
241 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
242 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
243 UserManager.DISALLOW_BLUETOOTH)) {
244 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800245 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
246 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800247 } else {
248 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
249 UserManager.DISALLOW_BLUETOOTH_SHARING));
250 }
251 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100252 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800253 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100254
Ajay Panicker467bc042017-02-22 12:23:15 -0800255 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
256 @Override
257 public void onChange(boolean unused) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800258 synchronized (this) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800259 if (isBluetoothPersistedStateOn()) {
260 if (isAirplaneModeOn()) {
261 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
262 } else {
263 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
264 }
265 }
266
267 int st = BluetoothAdapter.STATE_OFF;
268 try {
269 mBluetoothLock.readLock().lock();
270 if (mBluetooth != null) {
271 st = mBluetooth.getState();
272 }
273 } catch (RemoteException e) {
274 Slog.e(TAG, "Unable to call getState", e);
275 return;
276 } finally {
277 mBluetoothLock.readLock().unlock();
278 }
279
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800280 Slog.d(TAG,
281 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
282 st));
Ajay Panicker467bc042017-02-22 12:23:15 -0800283
284 if (isAirplaneModeOn()) {
285 // Clear registered LE apps to force shut-off
286 clearBleApps();
287
288 // If state is BLE_ON make sure we trigger disableBLE
289 if (st == BluetoothAdapter.STATE_BLE_ON) {
290 try {
291 mBluetoothLock.readLock().lock();
292 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700293 addActiveLog(
294 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
295 mContext.getPackageName(), false);
Ajay Panicker467bc042017-02-22 12:23:15 -0800296 mBluetooth.onBrEdrDown();
297 mEnable = false;
298 mEnableExternal = false;
299 }
300 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800301 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800302 } finally {
303 mBluetoothLock.readLock().unlock();
304 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800305 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800306 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
307 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800308 }
309 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800310 sendEnableMsg(mQuietEnableExternal,
311 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
312 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800313 }
314 }
315 }
316 };
317
fredcbf072a72012-05-09 16:52:50 -0700318 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700319 @Override
320 public void onReceive(Context context, Intent intent) {
321 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700322 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700323 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800324 if (DBG) {
325 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
326 }
fredc0f420372012-04-12 00:02:00 -0700327 if (newName != null) {
328 storeNameAndAddress(newName, null);
329 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700330 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
331 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
332 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800333 if (DBG) {
334 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
335 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700336 storeNameAndAddress(null, newAddress);
337 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800338 if (DBG) {
339 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
340 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700341 }
Stanley Tng873b5702017-05-01 21:27:31 -0700342 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
343 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
344 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
345 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800346 final String prevValue =
347 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
348 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700349
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800350 if (DBG) {
351 Slog.d(TAG,
352 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
353 + ", newValue=" + newValue);
354 }
Stanley Tng873b5702017-05-01 21:27:31 -0700355
356 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
357 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800358 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
359 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700360 mHandler.sendMessage(msg);
361 }
362 }
fredc0f420372012-04-12 00:02:00 -0700363 }
364 }
365 };
366
367 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700368 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700369
fredc0f420372012-04-12 00:02:00 -0700370 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700371
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700372 mWirelessConsentRequired = context.getResources()
373 .getBoolean(com.android.internal.R.bool.config_wirelessConsentRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700374
Marie Janssene54b4222017-03-16 18:10:59 -0700375 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700376 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800377 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800378 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700379 mBinding = false;
380 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700381 mEnable = false;
382 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800383 mQuietEnableExternal = false;
384 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700385 mAddress = null;
386 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800387 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700388 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700389 // Observe BLE scan only mode settings change.
390 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700391 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
392 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700393
Stanley Tngfe8c8332018-06-19 08:48:10 -0700394 // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
395 boolean isHearingAidEnabled;
396 String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
397 if (!TextUtils.isEmpty(value)) {
398 isHearingAidEnabled = Boolean.parseBoolean(value);
399 Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
400 FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
401 }
402
Stanley Tng873b5702017-05-01 21:27:31 -0700403 IntentFilter filter = new IntentFilter();
404 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
405 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
406 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700407 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700408 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700409
fredc0f420372012-04-12 00:02:00 -0700410 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800411 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800412 if (DBG) {
413 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
414 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800415 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700416 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200417
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800418 String airplaneModeRadios =
419 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
420 if (airplaneModeRadios == null || airplaneModeRadios.contains(
421 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800422 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800423 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
424 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800425 }
426
Marie Janssen59804562016-12-28 14:13:21 -0800427 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200428 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800429 // Check if device is configured with no home screen, which implies no SystemUI.
430 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
431 if (!noHome) {
432 systemUiUid = mContext.getPackageManager()
433 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
434 UserHandle.USER_SYSTEM);
435 }
436 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200437 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700438 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700439 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200440 }
Marie Janssen59804562016-12-28 14:13:21 -0800441 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700442 }
443
fredc649fe492012-04-19 01:07:18 -0700444 /**
445 * Returns true if airplane mode is currently on
446 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800447 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700448 return Settings.Global.getInt(mContext.getContentResolver(),
449 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700450 }
451
Arthur Hsu2433baf2018-01-11 11:05:11 -0800452 private boolean supportBluetoothPersistedState() {
453 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
454 }
455
fredc649fe492012-04-19 01:07:18 -0700456 /**
457 * Returns true if the Bluetooth saved state is "on"
458 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800459 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800460 if (!supportBluetoothPersistedState()) {
461 return false;
462 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800463 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
464 if (DBG) {
465 Slog.d(TAG, "Bluetooth persisted state: " + state);
466 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700467 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800468 }
469
470 /**
471 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
472 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800473 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800474 if (!supportBluetoothPersistedState()) {
475 return false;
476 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800477 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
478 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700479 }
480
481 /**
482 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700483 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800484 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800485 if (DBG) {
486 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
487 }
Marie Janssenfa630682016-12-15 13:51:30 -0800488 // waive WRITE_SECURE_SETTINGS permission check
489 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800490 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800491 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700492 }
493
494 /**
495 * Returns true if the Bluetooth Adapter's name and address is
496 * locally cached
497 * @return
498 */
fredc0f420372012-04-12 00:02:00 -0700499 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800500 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700501 }
502
fredc649fe492012-04-19 01:07:18 -0700503 /**
504 * Retrieve the Bluetooth Adapter's name and address and save it in
505 * in the local cache
506 */
fredc0f420372012-04-12 00:02:00 -0700507 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800508 if (DBG) {
509 Slog.d(TAG, "Loading stored name and address");
510 }
511 if (mContext.getResources()
512 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
513 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
514 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700515 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800516 if (DBG) {
517 Slog.d(TAG, "invalid bluetooth name and address stored");
518 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700519 return;
520 }
fredc0f420372012-04-12 00:02:00 -0700521 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
522 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800523 if (DBG) {
524 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
525 }
fredc0f420372012-04-12 00:02:00 -0700526 }
527
fredc649fe492012-04-19 01:07:18 -0700528 /**
529 * Save the Bluetooth name and address in the persistent store.
530 * Only non-null values will be saved.
531 * @param name
532 * @param address
533 */
fredc0f420372012-04-12 00:02:00 -0700534 private void storeNameAndAddress(String name, String address) {
535 if (name != null) {
536 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700537 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800538 if (DBG) {
539 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
540 SECURE_SETTINGS_BLUETOOTH_NAME));
541 }
fredc0f420372012-04-12 00:02:00 -0700542 }
543
544 if (address != null) {
545 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800546 mAddress = address;
547 if (DBG) {
548 Slog.d(TAG,
549 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
550 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
551 }
fredc0f420372012-04-12 00:02:00 -0700552 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700553
554 if ((name != null) && (address != null)) {
555 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
556 }
fredc0f420372012-04-12 00:02:00 -0700557 }
558
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800559 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700560 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700561 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700562 return null;
563 }
fredc0f420372012-04-12 00:02:00 -0700564 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
565 msg.obj = callback;
566 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700567
568 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700569 }
570
571 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700572 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700573 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700574 return;
575 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800576 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700577 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
578 msg.obj = callback;
579 mHandler.sendMessage(msg);
580 }
581
582 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800583 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800584 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800585 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
586 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800587 }
fredc0f420372012-04-12 00:02:00 -0700588 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
589 msg.obj = callback;
590 mHandler.sendMessage(msg);
591 }
592
593 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800594 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800595 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800596 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
597 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800598 }
fredc0f420372012-04-12 00:02:00 -0700599 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
600 msg.obj = callback;
601 mHandler.sendMessage(msg);
602 }
603
604 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800605 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
606 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700607 return false;
608 }
609
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700610 try {
611 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800612 if (mBluetooth != null) {
613 return mBluetooth.isEnabled();
614 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700615 } catch (RemoteException e) {
616 Slog.e(TAG, "isEnabled()", e);
617 } finally {
618 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700619 }
620 return false;
621 }
622
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700623 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800624 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800625 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700626 return BluetoothAdapter.STATE_OFF;
627 }
628
629 try {
630 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800631 if (mBluetooth != null) {
632 return mBluetooth.getState();
633 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700634 } catch (RemoteException e) {
635 Slog.e(TAG, "getState()", e);
636 } finally {
637 mBluetoothLock.readLock().unlock();
638 }
639 return BluetoothAdapter.STATE_OFF;
640 }
641
Nitin Arorad055adb2015-03-02 15:03:51 -0800642 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800643 private String mPackageName;
644
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800645 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800646 mPackageName = packageName;
647 }
648
Nitin Arorad055adb2015-03-02 15:03:51 -0800649 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800650 if (DBG) {
651 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800652 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700653
654 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
655 IBinder token = entry.getKey();
656 ClientDeathRecipient deathRec = entry.getValue();
657 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700658 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700659 break;
660 }
661 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800662 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800663
Marie Janssen59804562016-12-28 14:13:21 -0800664 public String getPackageName() {
665 return mPackageName;
666 }
667 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800668
Wei Wang67d84162015-04-26 17:04:29 -0700669 @Override
670 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700671 if (isAirplaneModeOn() && !mEnable) {
672 return false;
673 }
Wei Wang67d84162015-04-26 17:04:29 -0700674 try {
Jack He8caab152018-03-02 13:08:36 -0800675 return Settings.Global.getInt(mContentResolver,
676 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700677 } catch (SettingNotFoundException e) {
678 }
679 return false;
680 }
681
Wei Wange4a744b2015-06-11 17:50:29 -0700682 // Monitor change of BLE scan only mode settings.
683 private void registerForBleScanModeChange() {
684 ContentObserver contentObserver = new ContentObserver(null) {
685 @Override
686 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800687 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800688 // Nothing to do
689 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800690 }
691 // BLE scan is not available.
692 disableBleScanMode();
693 clearBleApps();
694 try {
695 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800696 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700697 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
698 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800699 mBluetooth.onBrEdrDown();
700 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800701 } catch (RemoteException e) {
702 Slog.e(TAG, "error when disabling bluetooth", e);
703 } finally {
704 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700705 }
706 }
707 };
708
709 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800710 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
711 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700712 }
713
714 // Disable ble scan only mode.
715 private void disableBleScanMode() {
716 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700717 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700718 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800719 if (DBG) {
720 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
721 }
Wei Wange4a744b2015-06-11 17:50:29 -0700722 mEnable = false;
723 }
724 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700725 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700726 } finally {
727 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700728 }
729 }
730
Marie Janssen59804562016-12-28 14:13:21 -0800731 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
732 ClientDeathRecipient r = mBleApps.get(token);
733 if (r == null && enable) {
734 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
735 try {
736 token.linkToDeath(deathRec, 0);
737 } catch (RemoteException ex) {
738 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 }
Marie Janssen59804562016-12-28 14:13:21 -0800740 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800741 if (DBG) {
742 Slog.d(TAG, "Registered for death of " + packageName);
743 }
Marie Janssen59804562016-12-28 14:13:21 -0800744 } else if (!enable && r != null) {
745 // Unregister death recipient as the app goes away.
746 token.unlinkToDeath(r, 0);
747 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800748 if (DBG) {
749 Slog.d(TAG, "Unregistered for death of " + packageName);
750 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800751 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800752 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800753 if (DBG) {
754 Slog.d(TAG, appCount + " registered Ble Apps");
755 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800756 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700757 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800758 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800759 if (appCount == 0 && !mEnableExternal) {
760 sendBrEdrDownCallback();
761 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800762 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800763 }
764
Wei Wange4a744b2015-06-11 17:50:29 -0700765 // Clear all apps using BLE scan only mode.
766 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800767 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700768 }
769
Marie Janssen59804562016-12-28 14:13:21 -0800770 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800771 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800772 if (DBG) {
773 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
774 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800775 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
777
778 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700779 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800780 */
Myles Watson304ebf22018-05-11 08:47:24 -0700781 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800782 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700783 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800784 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700785 try {
786 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800787 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700788 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800789 return;
790 }
791 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
792 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800793 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800794 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800795 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700796 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800797 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700798 } finally {
799 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800800 }
801 }
802
803 /**
804 * Inform BluetoothAdapter instances that BREDR part is down
805 * and turn off all service and stack if no LE app needs it
806 */
807 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800808 if (DBG) {
809 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
810 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700811
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700812 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700813 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700814 return;
815 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800816
Martin Brabhamc2b06222017-02-27 16:55:07 -0800817 if (isBleAppPresent()) {
818 // Need to stay at BLE ON. Disconnect all Gatt connections
819 try {
820 mBluetoothGatt.unregAll();
821 } catch (RemoteException e) {
822 Slog.e(TAG, "Unable to disconnect all apps.", e);
823 }
824 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800825 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700826 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800827 if (mBluetooth != null) {
828 mBluetooth.onBrEdrDown();
829 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700830 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700831 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700832 } finally {
833 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800834 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800835 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800836
Nitin Arorad055adb2015-03-02 15:03:51 -0800837 }
838
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800839 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100840 if (isBluetoothDisallowed()) {
841 if (DBG) {
842 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
843 }
844 return false;
845 }
846
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700847 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800848 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700849
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700850 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800851 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
852 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700853 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800854 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
855
856 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700857 throw new SecurityException("no permission to enable Bluetooth quietly");
858 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800859
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800860 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800861 mQuietEnableExternal = true;
862 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800863 sendEnableMsg(true,
864 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800865 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700866 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700867 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700868
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700869 public boolean enable(String packageName) throws RemoteException {
870 final int callingUid = Binder.getCallingUid();
871 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
872
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100873 if (isBluetoothDisallowed()) {
874 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800875 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100876 }
877 return false;
878 }
879
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700880 if (!callerSystem) {
881 if (!checkIfCallerIsForegroundUser()) {
882 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
883 return false;
884 }
885
886 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
887 "Need BLUETOOTH ADMIN permission");
888
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700889 if (!isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800890 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700891 return false;
892 }
fredcf2458862012-04-16 15:18:27 -0700893 }
894
Zhihai Xu401202b2012-12-03 11:36:21 -0800895 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800896 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
897 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700898 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800899
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800900 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800901 mQuietEnableExternal = false;
902 mEnableExternal = true;
903 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800904 sendEnableMsg(false,
905 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800906 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800907 if (DBG) {
908 Slog.d(TAG, "enable returning");
909 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800910 return true;
fredc0f420372012-04-12 00:02:00 -0700911 }
912
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700913 public boolean disable(String packageName, boolean persist) throws RemoteException {
914 final int callingUid = Binder.getCallingUid();
915 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700916
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700917 if (!callerSystem) {
918 if (!checkIfCallerIsForegroundUser()) {
919 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
920 return false;
921 }
922
923 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
924 "Need BLUETOOTH ADMIN permission");
925
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700926 if (isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800927 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700928 return false;
929 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700930 }
931
fredcf2458862012-04-16 15:18:27 -0700932 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800933 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700934 }
fredcf2458862012-04-16 15:18:27 -0700935
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800936 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800937 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800938 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800939 }
940 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800941 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
942 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800943 }
fredc0f420372012-04-12 00:02:00 -0700944 return true;
945 }
946
baishengf62d8692018-01-25 18:07:24 +0800947 private boolean startConsentUiIfNeeded(String packageName,
948 int callingUid, String intentAction) throws RemoteException {
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700949 if (checkBluetoothPermissionWhenWirelessConsentRequired()) {
baishengf62d8692018-01-25 18:07:24 +0800950 return false;
951 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700952 try {
953 // Validate the package only if we are going to use it
954 ApplicationInfo applicationInfo = mContext.getPackageManager()
955 .getApplicationInfoAsUser(packageName,
956 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
957 UserHandle.getUserId(callingUid));
958 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800959 throw new SecurityException("Package " + packageName
960 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700961 }
962
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000963 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000964 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800965 intent.setFlags(
966 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000967 try {
968 mContext.startActivity(intent);
969 } catch (ActivityNotFoundException e) {
970 // Shouldn't happen
971 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
972 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700973 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000974 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700975 } catch (PackageManager.NameNotFoundException e) {
976 throw new RemoteException(e.getMessage());
977 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700978 }
979
baishengf62d8692018-01-25 18:07:24 +0800980 /**
981 * Check if the caller must still pass permission check or if the caller is exempted
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700982 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED check.
baishengf62d8692018-01-25 18:07:24 +0800983 *
984 * Commands from some callers may be exempted from triggering the consent UI when
985 * enabling bluetooth. This exemption is checked via the
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700986 * MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED and allows calls to skip
baishengf62d8692018-01-25 18:07:24 +0800987 * the consent UI where it may otherwise be required.
988 *
989 * @hide
990 */
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700991 private boolean checkBluetoothPermissionWhenWirelessConsentRequired() {
baishengf62d8692018-01-25 18:07:24 +0800992 int result = mContext.checkCallingPermission(
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700993 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED);
baishengf62d8692018-01-25 18:07:24 +0800994 return result == PackageManager.PERMISSION_GRANTED;
995 }
996
fredc649fe492012-04-19 01:07:18 -0700997 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700998 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800999 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
1000 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -07001001 }
1002
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001003 try {
1004 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001005 if (mUnbinding) {
1006 return;
1007 }
fredc0f420372012-04-12 00:02:00 -07001008 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001009 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001010 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001011 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001012 //Unregister callback object
1013 try {
1014 mBluetooth.unregisterCallback(mBluetoothCallback);
1015 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001016 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001017 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001018 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001019 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001020 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001021 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001022 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001023 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001024 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001025 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001026 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001027 } finally {
1028 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001029 }
1030 }
1031
Matthew Xieddf7e472013-03-01 18:41:02 -08001032 public IBluetoothGatt getBluetoothGatt() {
1033 // sync protection
1034 return mBluetoothGatt;
1035 }
1036
Benjamin Franze8b98922014-11-12 15:57:54 +00001037 @Override
1038 public boolean bindBluetoothProfileService(int bluetoothProfile,
1039 IBluetoothProfileServiceConnection proxy) {
1040 if (!mEnable) {
1041 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001042 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1043 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001044 }
1045 return false;
1046 }
1047 synchronized (mProfileServices) {
1048 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1049 if (psc == null) {
1050 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001051 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1052 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001053 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001054
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001055 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1056 return false;
1057 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001058
1059 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001060 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001061 if (!psc.bindService()) {
1062 return false;
1063 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001064
Benjamin Franze8b98922014-11-12 15:57:54 +00001065 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001066 }
1067 }
1068
1069 // Introducing a delay to give the client app time to prepare
1070 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1071 addProxyMsg.arg1 = bluetoothProfile;
1072 addProxyMsg.obj = proxy;
1073 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1074 return true;
1075 }
1076
1077 @Override
1078 public void unbindBluetoothProfileService(int bluetoothProfile,
1079 IBluetoothProfileServiceConnection proxy) {
1080 synchronized (mProfileServices) {
1081 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1082 if (psc == null) {
1083 return;
1084 }
1085 psc.removeProxy(proxy);
1086 }
1087 }
1088
1089 private void unbindAllBluetoothProfileServices() {
1090 synchronized (mProfileServices) {
1091 for (Integer i : mProfileServices.keySet()) {
1092 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001093 try {
1094 mContext.unbindService(psc);
1095 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001096 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001097 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001098 psc.removeAllProxies();
1099 }
1100 mProfileServices.clear();
1101 }
1102 }
1103
1104 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001105 * Send enable message and set adapter name and address. Called when the boot phase becomes
1106 * PHASE_SYSTEM_SERVICES_READY.
1107 */
1108 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001109 if (DBG) {
1110 Slog.d(TAG, "Bluetooth boot completed");
1111 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001112 UserManagerInternal userManagerInternal =
1113 LocalServices.getService(UserManagerInternal.class);
1114 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001115 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001116 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001117 return;
1118 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001119 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001120 if (DBG) {
1121 Slog.d(TAG, "Auto-enabling Bluetooth.");
1122 }
Jack He8caab152018-03-02 13:08:36 -08001123 sendEnableMsg(mQuietEnableExternal,
1124 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1125 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001126 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001127 if (DBG) {
1128 Slog.d(TAG, "Getting adapter name and address");
1129 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001130 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1131 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001132 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001133 }
1134
1135 /**
1136 * Called when switching to a different foreground user.
1137 */
1138 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001139 if (DBG) {
1140 Slog.d(TAG, "User " + userHandle + " switched");
1141 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001142 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1143 }
1144
1145 /**
1146 * Called when user is unlocked.
1147 */
1148 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001149 if (DBG) {
1150 Slog.d(TAG, "User " + userHandle + " unlocked");
1151 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001152 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001153 }
1154
1155 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001156 * This class manages the clients connected to a given ProfileService
1157 * and maintains the connection with that service.
1158 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001159 private final class ProfileServiceConnections
1160 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001161 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001162 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001163 IBinder mService;
1164 ComponentName mClassName;
1165 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001166 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001167
1168 ProfileServiceConnections(Intent intent) {
1169 mService = null;
1170 mClassName = null;
1171 mIntent = intent;
1172 }
1173
Benjamin Franz5b614592014-12-09 18:58:45 +00001174 private boolean bindService() {
jonerlin37fc85d2018-08-09 16:39:43 +08001175 int state = BluetoothAdapter.STATE_OFF;
1176 try {
1177 mBluetoothLock.readLock().lock();
1178 if (mBluetooth != null) {
1179 state = mBluetooth.getState();
1180 }
1181 } catch (RemoteException e) {
1182 Slog.e(TAG, "Unable to call getState", e);
1183 return false;
1184 } finally {
1185 mBluetoothLock.readLock().unlock();
1186 }
1187
1188 if (!mEnable || state != BluetoothAdapter.STATE_ON) {
1189 if (DBG) {
1190 Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
1191 }
1192 return false;
1193 }
1194
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001195 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1196 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001197 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1198 msg.obj = this;
1199 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001200 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001201 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001202 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001203 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001204 }
1205
1206 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1207 mProxies.register(proxy);
1208 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001209 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001210 proxy.onServiceConnected(mClassName, mService);
1211 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001212 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001213 }
1214 } else {
1215 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1216 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1217 msg.obj = this;
1218 mHandler.sendMessage(msg);
1219 }
1220 }
1221 }
1222
1223 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1224 if (proxy != null) {
1225 if (mProxies.unregister(proxy)) {
1226 try {
1227 proxy.onServiceDisconnected(mClassName);
1228 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001229 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001230 }
1231 }
1232 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001233 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001234 }
1235 }
1236
1237 private void removeAllProxies() {
1238 onServiceDisconnected(mClassName);
1239 mProxies.kill();
1240 }
1241
1242 @Override
1243 public void onServiceConnected(ComponentName className, IBinder service) {
1244 // remove timeout message
1245 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1246 mService = service;
1247 mClassName = className;
1248 try {
1249 mService.linkToDeath(this, 0);
1250 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001251 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001252 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001253
1254 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001255 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001256 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001257 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001258 mInvokingProxyCallbacks = true;
1259
1260 final int n = mProxies.beginBroadcast();
1261 try {
1262 for (int i = 0; i < n; i++) {
1263 try {
1264 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1265 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001266 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001267 }
1268 }
1269 } finally {
1270 mProxies.finishBroadcast();
1271 mInvokingProxyCallbacks = false;
1272 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001273 }
1274
1275 @Override
1276 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001277 if (mService == null) {
1278 return;
1279 }
Chienyuan177156b2018-12-18 10:40:25 +08001280 try {
1281 mService.unlinkToDeath(this, 0);
1282 } catch (NoSuchElementException e) {
1283 Log.e(TAG, "error unlinking to death", e);
1284 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001285 mService = null;
1286 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001287
1288 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001289 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001290 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001291 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001292 mInvokingProxyCallbacks = true;
1293
1294 final int n = mProxies.beginBroadcast();
1295 try {
1296 for (int i = 0; i < n; i++) {
1297 try {
1298 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1299 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001300 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001301 }
1302 }
1303 } finally {
1304 mProxies.finishBroadcast();
1305 mInvokingProxyCallbacks = false;
1306 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001307 }
1308
1309 @Override
1310 public void binderDied() {
1311 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001312 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001313 }
1314 onServiceDisconnected(mClassName);
1315 // Trigger rebind
1316 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1317 msg.obj = this;
1318 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1319 }
1320 }
1321
fredcbf072a72012-05-09 16:52:50 -07001322 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001323 try {
1324 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001325 if (DBG) {
1326 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1327 + " receivers.");
1328 }
1329 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001330 try {
1331 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1332 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001333 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001334 }
fredcbf072a72012-05-09 16:52:50 -07001335 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001336 } finally {
1337 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001338 }
fredcbf072a72012-05-09 16:52:50 -07001339 }
1340
1341 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001342 * Inform BluetoothAdapter instances that Adapter service is up
1343 */
1344 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001345 try {
1346 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001347 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1348 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001349 try {
1350 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001351 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001352 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001353 }
1354 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001355 } finally {
1356 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001357 }
1358 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001359
Zhihai Xu40874a02012-10-08 17:57:03 -07001360 /**
fredcbf072a72012-05-09 16:52:50 -07001361 * Inform BluetoothAdapter instances that Adapter service is down
1362 */
1363 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001364 try {
1365 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001366 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1367 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001368 try {
1369 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001370 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001371 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001372 }
1373 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001374 } finally {
1375 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001376 }
1377 }
Svet Ganov408abf72015-05-12 19:13:36 -07001378
fredc0f420372012-04-12 00:02:00 -07001379 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001380 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001381
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001382 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1383 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001384 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001385 }
1386
Svet Ganov408abf72015-05-12 19:13:36 -07001387 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1388 != PackageManager.PERMISSION_GRANTED) {
1389 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1390 }
1391
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001392 try {
1393 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001394 if (mBluetooth != null) {
1395 return mBluetooth.getAddress();
1396 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001397 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001398 Slog.e(TAG,
1399 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1400 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001401 } finally {
1402 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001403 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001404
Matthew Xiecdce0b92012-07-12 19:06:15 -07001405 // mAddress is accessed from outside.
1406 // It is alright without a lock. Here, bluetooth is off, no other thread is
1407 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001408 return mAddress;
1409 }
fredc649fe492012-04-19 01:07:18 -07001410
fredc0f420372012-04-12 00:02:00 -07001411 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001412 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001413
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001414 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1415 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001416 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001417 }
1418
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001419 try {
1420 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001421 if (mBluetooth != null) {
1422 return mBluetooth.getName();
1423 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001424 } catch (RemoteException e) {
1425 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1426 } finally {
1427 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001428 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001429
Matthew Xiecdce0b92012-07-12 19:06:15 -07001430 // mName is accessed from outside.
1431 // It alright without a lock. Here, bluetooth is off, no other thread is
1432 // changing mName
fredc0f420372012-04-12 00:02:00 -07001433 return mName;
1434 }
1435
fredc0f420372012-04-12 00:02:00 -07001436 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001437 public void onServiceConnected(ComponentName componentName, IBinder service) {
1438 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001439 if (DBG) {
1440 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1441 }
fredc0f420372012-04-12 00:02:00 -07001442 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001443 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001444 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001445 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001446 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1447 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001448 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001449 return;
1450 }
fredc0f420372012-04-12 00:02:00 -07001451 msg.obj = service;
1452 mHandler.sendMessage(msg);
1453 }
1454
Marie Janssencb21ad72016-12-13 10:51:02 -08001455 public void onServiceDisconnected(ComponentName componentName) {
1456 // Called if we unexpectedly disconnect.
1457 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001458 if (DBG) {
1459 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1460 }
fredc0f420372012-04-12 00:02:00 -07001461 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001462 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001463 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001464 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001465 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1466 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001467 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001468 return;
1469 }
fredc0f420372012-04-12 00:02:00 -07001470 mHandler.sendMessage(msg);
1471 }
1472 }
1473
1474 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1475
Zhihai Xu40874a02012-10-08 17:57:03 -07001476 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001477 boolean mGetNameAddressOnly = false;
1478
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001479 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001480 super(looper);
1481 }
1482
fredc0f420372012-04-12 00:02:00 -07001483 @Override
1484 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001485 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001486 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001487 if (DBG) {
1488 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1489 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001490 try {
1491 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001492 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001493 if (DBG) {
1494 Slog.d(TAG, "Binding to service to get name and address");
1495 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001496 mGetNameAddressOnly = true;
1497 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1498 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1499 Intent i = new Intent(IBluetooth.class.getName());
1500 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001501 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1502 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001503 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1504 } else {
1505 mBinding = true;
1506 }
1507 } else if (mBluetooth != null) {
1508 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001509 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001510 } catch (RemoteException re) {
1511 Slog.e(TAG, "Unable to grab names", re);
1512 }
1513 if (mGetNameAddressOnly && !mEnable) {
1514 unbindAndFinish();
1515 }
1516 mGetNameAddressOnly = false;
1517 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001518 } finally {
1519 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001520 }
1521 break;
1522
Matthew Xiecdce0b92012-07-12 19:06:15 -07001523 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001524 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001525 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001526 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001527 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1528 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001529
1530 // Use service interface to get the exact state
1531 try {
1532 mBluetoothLock.readLock().lock();
1533 if (mBluetooth != null) {
1534 int state = mBluetooth.getState();
1535 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001536 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001537 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001538 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001539 break;
1540 }
1541 }
1542 } catch (RemoteException e) {
1543 Slog.e(TAG, "", e);
1544 } finally {
1545 mBluetoothLock.readLock().unlock();
1546 }
1547
1548 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001549 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001550 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001551 } else {
1552 //
1553 // We need to wait until transitioned to STATE_OFF and
1554 // the previous Bluetooth process has exited. The
1555 // waiting period has three components:
1556 // (a) Wait until the local state is STATE_OFF. This
1557 // is accomplished by "waitForOnOff(false, true)".
1558 // (b) Wait until the STATE_OFF state is updated to
1559 // all components.
1560 // (c) Wait until the Bluetooth process exits, and
1561 // ActivityManager detects it.
1562 // The waiting for (b) and (c) is accomplished by
1563 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1564 // message. On slower devices, that delay needs to be
1565 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1566 //
1567 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001568 Message restartMsg =
1569 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1570 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001571 }
fredc649fe492012-04-19 01:07:18 -07001572 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001573
fredc0f420372012-04-12 00:02:00 -07001574 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001575 if (DBG) {
1576 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1577 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001578 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1579 if (mEnable && mBluetooth != null) {
1580 waitForOnOff(true, false);
1581 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001582 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001583 waitForOnOff(false, false);
1584 } else {
1585 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001586 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001587 }
fredc0f420372012-04-12 00:02:00 -07001588 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001589
Stanley Tng873b5702017-05-01 21:27:31 -07001590 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001591 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1592 if (DBG) {
1593 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001594 }
Jack He8caab152018-03-02 13:08:36 -08001595 persistBluetoothSetting(BLUETOOTH_OFF);
1596 mEnableExternal = false;
1597 sendDisableMsg(
1598 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1599 mContext.getPackageName());
1600 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1601 if (DBG) {
1602 Slog.d(TAG, "Restore Bluetooth state to enabled");
1603 }
1604 mQuietEnableExternal = false;
1605 mEnableExternal = true;
1606 // waive WRITE_SECURE_SETTINGS permission check
1607 sendEnableMsg(false,
1608 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1609 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001610 }
1611 break;
1612
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001613 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001614 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001615 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001616 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001617 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001618 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001619 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001620 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001621 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001622 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001623 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1624 IBluetoothStateChangeCallback callback =
1625 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001626 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001627 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001628 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001629 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1630 IBluetoothStateChangeCallback callback =
1631 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001632 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001633 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001634 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001635 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001636 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001637 if (psc == null) {
1638 break;
1639 }
1640 IBluetoothProfileServiceConnection proxy =
1641 (IBluetoothProfileServiceConnection) msg.obj;
1642 psc.addProxy(proxy);
1643 break;
1644 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001645 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001646 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1647 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1648 if (psc == null) {
1649 break;
1650 }
1651 psc.bindService();
1652 break;
1653 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001654 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1655 if (DBG) {
1656 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1657 }
fredc0f420372012-04-12 00:02:00 -07001658
1659 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001660 try {
1661 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001662 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001663 mBluetoothGatt =
1664 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001665 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001666 break;
1667 } // else must be SERVICE_IBLUETOOTH
1668
1669 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001670 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001671
fredc0f420372012-04-12 00:02:00 -07001672 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001673 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001674 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001675
Ajay Panicker4bb48302016-03-31 14:14:27 -07001676 if (!isNameAndAddressSet()) {
1677 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1678 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001679 if (mGetNameAddressOnly) {
1680 return;
1681 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001682 }
1683
Matthew Xiecdce0b92012-07-12 19:06:15 -07001684 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001685 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001686 mBluetooth.registerCallback(mBluetoothCallback);
1687 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001688 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001689 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001690 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001691 sendBluetoothServiceUpCallback();
1692
Matthew Xiecdce0b92012-07-12 19:06:15 -07001693 //Do enable request
1694 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001695 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001696 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001697 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001698 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001699 } else {
1700 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001701 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001702 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001703 }
1704 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001705 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001706 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001707 } finally {
1708 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001709 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001710
1711 if (!mEnable) {
1712 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001713 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001714 waitForOnOff(false, false);
1715 }
fredc649fe492012-04-19 01:07:18 -07001716 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001717 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001718 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001719 int prevState = msg.arg1;
1720 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001721 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001722 Slog.d(TAG,
1723 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1724 prevState) + " > " + BluetoothAdapter.nameForState(
1725 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001726 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001727 mState = newState;
1728 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001729 // handle error state transition case from TURNING_ON to OFF
1730 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001731 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1732 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001733 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001734 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001735 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1736 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001737 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001738 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001739 // If we tried to enable BT while BT was in the process of shutting down,
1740 // wait for the BT process to fully tear down and then force a restart
1741 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001742 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1743 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001744 if (mEnable) {
1745 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1746 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001747 Message restartMsg =
1748 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001749 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1750 }
1751 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001752 if (newState == BluetoothAdapter.STATE_ON
1753 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001754 // bluetooth is working, reset the counter
1755 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001756 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001757 mErrorRecoveryRetryCounter = 0;
1758 }
1759 }
fredc649fe492012-04-19 01:07:18 -07001760 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001761 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001762 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001763 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001764 try {
1765 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001766 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1767 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001768 if (mBluetooth == null) {
1769 break;
1770 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001771 mBluetooth = null;
1772 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1773 mBluetoothGatt = null;
1774 break;
1775 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001776 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001777 break;
1778 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001779 } finally {
1780 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301781 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001782
Marie Janssene54b4222017-03-16 18:10:59 -07001783 // log the unexpected crash
1784 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001785 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1786 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001787 if (mEnable) {
1788 mEnable = false;
1789 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001790 Message restartMsg =
1791 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1792 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001793 }
1794
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001795 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001796
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001797 // Send BT state broadcast to update
1798 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001799 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1800 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001801 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001802 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001803 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001804 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001805 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1806 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001807 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001808 }
1809
1810 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1811 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001812 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001813 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001814 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001815 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301816 /* Enable without persisting the setting as
1817 it doesnt change when IBluetooth
1818 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001819 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001820 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1821 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001822 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301823 break;
1824 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001825 case MESSAGE_TIMEOUT_BIND: {
1826 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1827 mBluetoothLock.writeLock().lock();
1828 mBinding = false;
1829 mBluetoothLock.writeLock().unlock();
1830 break;
1831 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001832 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001833 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001834 mBluetoothLock.writeLock().lock();
1835 mUnbinding = false;
1836 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001837 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001838 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001839
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001840 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001841 if (DBG) {
1842 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1843 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001844 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001845
Zhihai Xu40874a02012-10-08 17:57:03 -07001846 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001847 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001848 try {
1849 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001850 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001851 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001852 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001853 } catch (RemoteException re) {
1854 Slog.e(TAG, "Unable to unregister", re);
1855 } finally {
1856 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001857 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001858
1859 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1860 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1861 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1862 mState = BluetoothAdapter.STATE_OFF;
1863 }
1864 if (mState == BluetoothAdapter.STATE_OFF) {
1865 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1866 mState = BluetoothAdapter.STATE_TURNING_ON;
1867 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001868
1869 waitForOnOff(true, false);
1870
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001871 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1872 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1873 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001874
Benjamin Franze8b98922014-11-12 15:57:54 +00001875 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001876 // disable
Jack He8caab152018-03-02 13:08:36 -08001877 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1878 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001879 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001880 // Pbap service need receive STATE_TURNING_OFF intent to close
1881 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001882 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001883
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001884 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001885
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001886 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001887 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001888 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001889
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001890 try {
1891 mBluetoothLock.writeLock().lock();
1892 if (mBluetooth != null) {
1893 mBluetooth = null;
1894 // Unbind
1895 mContext.unbindService(mConnection);
1896 }
1897 mBluetoothGatt = null;
1898 } finally {
1899 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001900 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001901
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001902 //
1903 // If disabling Bluetooth times out, wait for an
1904 // additional amount of time to ensure the process is
1905 // shut down completely before attempting to restart.
1906 //
1907 if (didDisableTimeout) {
1908 SystemClock.sleep(3000);
1909 } else {
1910 SystemClock.sleep(100);
1911 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001912
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001913 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1914 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001915 // enable
Jack He8caab152018-03-02 13:08:36 -08001916 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1917 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001918 // mEnable flag could have been reset on disableBLE. Reenable it.
1919 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001920 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001921 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001922 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1923 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001924 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001925 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1926 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001927 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001928 }
John Spurlock8a985d22014-02-25 09:40:05 -05001929 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001930 break;
1931 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001932 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001933 if (DBG) {
1934 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1935 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001936 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1937
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001938 if (mEnable && !mBinding && (mBluetooth == null)) {
1939 // We should be connected, but we gave up for some
1940 // reason; maybe the Bluetooth service wasn't encryption
1941 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001942 if (DBG) {
1943 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1944 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001945 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001946 }
1947 }
fredc0f420372012-04-12 00:02:00 -07001948 }
1949 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001950 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001951
Zhihai Xu401202b2012-12-03 11:36:21 -08001952 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001953 mQuietEnable = quietMode;
1954
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001955 try {
1956 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001957 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001958 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001959 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1960 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001961 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001962 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001963 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001964 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001965 } else {
1966 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001967 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001968 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001969 //Enable bluetooth
1970 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001971 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001972 if (!mBluetooth.enable()) {
1973 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001974 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001975 } else {
1976 if (!mBluetooth.enableNoAutoConnect()) {
1977 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001978 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001979 }
1980 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001981 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001982 }
1983 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001984 } finally {
1985 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001986 }
1987 }
1988
Dianne Hackborn221ea892013-08-04 16:50:16 -07001989 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1990 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1991 intent.setComponent(comp);
1992 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001993 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001994 return false;
1995 }
1996 return true;
1997 }
1998
Zhihai Xu401202b2012-12-03 11:36:21 -08001999 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002000 try {
2001 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08002002 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002003 if (DBG) {
2004 Slog.d(TAG, "Sending off request.");
2005 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002006 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002007 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002008 }
2009 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002010 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002011 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002012 } finally {
2013 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002014 }
2015 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002016
2017 private boolean checkIfCallerIsForegroundUser() {
2018 int foregroundUser;
2019 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002020 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07002021 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00002022 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
2023 UserInfo ui = um.getProfileParent(callingUser);
2024 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002025 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07002026 boolean valid = false;
2027 try {
2028 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002029 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2030 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002031 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002032 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2033 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2034 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002035 }
2036 } finally {
2037 Binder.restoreCallingIdentity(callingIdentity);
2038 }
2039 return valid;
2040 }
2041
Nitin Arorad055adb2015-03-02 15:03:51 -08002042 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002043 if (DBG) {
2044 Slog.d(TAG,
2045 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2046 + BluetoothAdapter.nameForState(newState));
2047 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002048 // Send broadcast message to everyone else
2049 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2050 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2051 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2052 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2053 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2054 }
2055
Zhihai Xu40874a02012-10-08 17:57:03 -07002056 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002057 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002058 if (prevState == newState) { // No change. Nothing to do.
2059 return;
2060 }
2061 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002062 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002063 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002064 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002065
Marie Janssencb21ad72016-12-13 10:51:02 -08002066 if (newState == BluetoothAdapter.STATE_OFF) {
2067 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002068 if (DBG) {
2069 Slog.d(TAG, "Bluetooth is complete send Service Down");
2070 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002071 sendBluetoothServiceDownCallback();
2072 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002073 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002074 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002075 isStandardBroadcast = false;
2076
Marie Janssencb21ad72016-12-13 10:51:02 -08002077 } else if (!intermediate_off) {
2078 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002079 if (DBG) {
2080 Slog.d(TAG, "Bluetooth is in LE only mode");
2081 }
Myles Watson304ebf22018-05-11 08:47:24 -07002082 if (mBluetoothGatt != null || !mContext.getPackageManager()
2083 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2084 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002085 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002086 if (DBG) {
2087 Slog.d(TAG, "Binding Bluetooth GATT service");
2088 }
Myles Watson304ebf22018-05-11 08:47:24 -07002089 Intent i = new Intent(IBluetoothGatt.class.getName());
2090 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2091 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002092 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002093 sendBleStateChanged(prevState, newState);
2094 //Don't broadcase this as std intent
2095 isStandardBroadcast = false;
2096
2097 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002098 if (DBG) {
2099 Slog.d(TAG, "Intermediate off, back to LE only mode");
2100 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002101 // For LE only mode, broadcast as is
2102 sendBleStateChanged(prevState, newState);
2103 sendBluetoothStateCallback(false); // BT is OFF for general users
2104 // Broadcast as STATE_OFF
2105 newState = BluetoothAdapter.STATE_OFF;
2106 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002107 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002108 } else if (newState == BluetoothAdapter.STATE_ON) {
2109 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2110 sendBluetoothStateCallback(isUp);
2111 sendBleStateChanged(prevState, newState);
2112
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002113 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2114 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002115 sendBleStateChanged(prevState, newState);
2116 isStandardBroadcast = false;
2117
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002118 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2119 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002120 sendBleStateChanged(prevState, newState);
2121 }
2122
2123 if (isStandardBroadcast) {
2124 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2125 // Show prevState of BLE_ON as OFF to standard users
2126 prevState = BluetoothAdapter.STATE_OFF;
2127 }
2128 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2129 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2130 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2131 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2132 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002133 }
2134 }
2135
2136 /**
2137 * if on is true, wait for state become ON
2138 * if off is true, wait for state become OFF
2139 * if both on and off are false, wait for state not ON
2140 */
2141 private boolean waitForOnOff(boolean on, boolean off) {
2142 int i = 0;
2143 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002144 try {
2145 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002146 if (mBluetooth == null) {
2147 break;
2148 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002149 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002150 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2151 return true;
2152 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002153 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002154 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2155 return true;
2156 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002157 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002158 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2159 return true;
2160 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002161 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002162 } catch (RemoteException e) {
2163 Slog.e(TAG, "getState()", e);
2164 break;
2165 } finally {
2166 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002167 }
2168 if (on || off) {
2169 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002170 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002171 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002172 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002173 i++;
2174 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002175 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002176 return false;
2177 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002178
Jack He8caab152018-03-02 13:08:36 -08002179 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002180 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002181 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002182 }
2183
Jack He8caab152018-03-02 13:08:36 -08002184 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002185 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002186 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002187 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002188 }
2189
Jack He8caab152018-03-02 13:08:36 -08002190 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002191 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002192 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002193 mActiveLogs.remove();
2194 }
Jack He8caab152018-03-02 13:08:36 -08002195 mActiveLogs.add(
2196 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002197 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002198
2199 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2200 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2201 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2202 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002203 }
2204
Marie Janssene54b4222017-03-16 18:10:59 -07002205 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002206 synchronized (mCrashTimestamps) {
2207 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2208 mCrashTimestamps.removeFirst();
2209 }
2210 mCrashTimestamps.add(System.currentTimeMillis());
2211 mCrashes++;
2212 }
Marie Janssene54b4222017-03-16 18:10:59 -07002213 }
2214
Marie Janssen2977c3e2016-11-09 12:01:24 -08002215 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002216 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002217 try {
2218 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002219 if (mBluetooth != null) {
2220 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002221 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002222 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002223 } catch (RemoteException re) {
2224 Slog.e(TAG, "Unable to unregister", re);
2225 } finally {
2226 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002227 }
2228
2229 SystemClock.sleep(500);
2230
2231 // disable
Jack He8caab152018-03-02 13:08:36 -08002232 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2233 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002234 handleDisable();
2235
2236 waitForOnOff(false, true);
2237
2238 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002239
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002240 try {
2241 mBluetoothLock.writeLock().lock();
2242 if (mBluetooth != null) {
2243 mBluetooth = null;
2244 // Unbind
2245 mContext.unbindService(mConnection);
2246 }
2247 mBluetoothGatt = null;
2248 } finally {
2249 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002250 }
2251
2252 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2253 mState = BluetoothAdapter.STATE_OFF;
2254
Marie Janssen2977c3e2016-11-09 12:01:24 -08002255 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002256 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002257 }
2258
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002259 mEnable = false;
2260
2261 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2262 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002263 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002264 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2265 } else {
2266 // todo: notify user to power down and power up phone to make bluetooth work.
2267 }
2268 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002269
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002270 private boolean isBluetoothDisallowed() {
2271 long callingIdentity = Binder.clearCallingIdentity();
2272 try {
2273 return mContext.getSystemService(UserManager.class)
2274 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2275 } finally {
2276 Binder.restoreCallingIdentity(callingIdentity);
2277 }
2278 }
2279
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002280 /**
2281 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002282 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2283 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002284 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002285 * @param userId user to disable bluetooth sharing for.
2286 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002287 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002288 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002289 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2290 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002291 final int newState =
2292 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2293 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002294 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002295 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002296 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2297 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002298 } catch (Exception e) {
2299 // The component was not found, do nothing.
2300 }
2301 }
2302
Mike Lockwood726d4de2014-10-28 14:06:28 -07002303 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002304 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002305 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2306 return;
2307 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002308 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002309
2310 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2311
2312 if (!protoOut) {
2313 writer.println("Bluetooth Status");
2314 writer.println(" enabled: " + isEnabled());
2315 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2316 writer.println(" address: " + mAddress);
2317 writer.println(" name: " + mName);
2318 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002319 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002320 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2321 (int) (onDuration / (1000 * 60 * 60)),
2322 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2323 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002324 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002325 }
2326
Marie Janssena95924d2017-01-18 09:37:52 -08002327 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002328 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002329 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002330 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002331 for (ActiveLog log : mActiveLogs) {
2332 writer.println(" " + log);
2333 }
Marie Janssen59804562016-12-28 14:13:21 -08002334 }
2335
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002336 writer.println(
2337 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2338 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2339 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2340 }
Marie Janssene54b4222017-03-16 18:10:59 -07002341 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002342 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002343 }
2344
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002345 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2346 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002347 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002348 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002349 }
2350
Marie Janssena95924d2017-01-18 09:37:52 -08002351 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002352 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002353 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002354 // Add arg to produce output
2355 args = new String[1];
2356 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002357 }
Marie Janssen59804562016-12-28 14:13:21 -08002358 }
2359
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002360 if (mBluetoothBinder == null) {
2361 errorMsg = "Bluetooth Service not connected";
2362 } else {
2363 try {
2364 mBluetoothBinder.dump(fd, args);
2365 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002366 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002367 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002368 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002369 if (errorMsg != null) {
2370 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002371 if (protoOut) {
2372 return;
2373 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002374 writer.println(errorMsg);
2375 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002376 }
Jack He8caab152018-03-02 13:08:36 -08002377
2378 private static String getEnableDisableReasonString(int reason) {
2379 switch (reason) {
2380 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2381 return "APPLICATION_REQUEST";
2382 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2383 return "AIRPLANE_MODE";
2384 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2385 return "DISALLOWED";
2386 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2387 return "RESTARTED";
2388 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2389 return "START_ERROR";
2390 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2391 return "SYSTEM_BOOT";
2392 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2393 return "CRASH";
2394 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2395 return "USER_SWITCH";
2396 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2397 return "RESTORE_USER_SETTING";
2398 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2399 default: return "UNKNOWN[" + reason + "]";
2400 }
2401 }
fredc0f420372012-04-12 00:02:00 -07002402}