blob: aa426d3cd31f57c60a7f4c1fe5c8205f2523acab [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;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070056import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000057import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010058import android.os.UserManagerInternal;
59import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070060import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070061import android.provider.Settings.SettingNotFoundException;
Jeff Sharkey67609c72016-03-05 14:29:13 -070062import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000063import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070064
Arthur Hsuf3f95a92018-01-11 16:46:22 -080065import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060066import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010067import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010068
Mike Lockwood726d4de2014-10-28 14:06:28 -070069import java.io.FileDescriptor;
70import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000071import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080072import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080073import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000074import java.util.Map;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010075import java.util.concurrent.ConcurrentHashMap;
76import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070077
Marie Janssen59804562016-12-28 14:13:21 -080078
fredc0f420372012-04-12 00:02:00 -070079class BluetoothManagerService extends IBluetoothManager.Stub {
80 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070081 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070082
fredc0f420372012-04-12 00:02:00 -070083 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
84 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070085
Myles Watsonb5cd11a2017-11-27 16:42:11 -080086 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
87 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
88 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070089
90 private static final int ACTIVE_LOG_MAX_SIZE = 20;
91 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070092
fredc0f420372012-04-12 00:02:00 -070093 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053094 //Maximum msec to wait for service restart
95 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -080096 //Maximum msec to wait for restart due to error
97 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -070098 //Maximum msec to delay MESSAGE_USER_SWITCHED
99 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000100 // Delay for the addProxy function in msec
101 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700102
103 private static final int MESSAGE_ENABLE = 1;
104 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700105 private static final int MESSAGE_REGISTER_ADAPTER = 20;
106 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
107 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
108 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
109 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
110 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530111 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700112 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
113 private static final int MESSAGE_TIMEOUT_BIND = 100;
114 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700115 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700116 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700117 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000118 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
119 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700120 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
121
122 private static final int RESTORE_SETTING_TO_ON = 1;
123 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800124
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700125 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800126
Zhihai Xu401202b2012-12-03 11:36:21 -0800127 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800128 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800129 // Bluetooth persisted setting is on
130 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800131 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800132 // Bluetooth persisted setting is on
133 // but Airplane mode will affect Bluetooth state at start up
134 // and Airplane mode will have higher priority.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800135 private static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700136
Matthew Xieddf7e472013-03-01 18:41:02 -0800137 private static final int SERVICE_IBLUETOOTH = 1;
138 private static final int SERVICE_IBLUETOOTHGATT = 2;
139
fredc0f420372012-04-12 00:02:00 -0700140 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700141
142 // Locks are not provided for mName and mAddress.
143 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700144 private String mAddress;
145 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700146 private final ContentResolver mContentResolver;
147 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
148 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800149 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700150 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800151 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800152 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700153 private boolean mBinding;
154 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800155
Zhihai Xu401202b2012-12-03 11:36:21 -0800156 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700157 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800158 private boolean mEnable;
159
Jack He8caab152018-03-02 13:08:36 -0800160 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700161 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
162 }
163
Marie Janssen59804562016-12-28 14:13:21 -0800164 /**
165 * Used for tracking apps that enabled / disabled Bluetooth.
166 */
167 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800168 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800169 private String mPackageName;
170 private boolean mEnable;
171 private long mTimestamp;
172
Jack He8caab152018-03-02 13:08:36 -0800173 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
174 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800175 mPackageName = packageName;
176 mEnable = enable;
177 mTimestamp = timestamp;
178 }
179
Marie Janssen59804562016-12-28 14:13:21 -0800180 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800181 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
182 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800183 }
184
185 }
186
Jack He8caab152018-03-02 13:08:36 -0800187 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
188 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700189 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700190 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800191
192 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800193 // synchronize with broadcast receiver.
194 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800195 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800196
197 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800198 private Map<IBinder, ClientDeathRecipient> mBleApps =
199 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800200
Zhihai Xu40874a02012-10-08 17:57:03 -0700201 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700202 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800203 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200204 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700205
Benjamin Franze8b98922014-11-12 15:57:54 +0000206 // Save a ProfileServiceConnections object for each of the bound
207 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800208 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000209
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700210 private final boolean mPermissionReviewRequired;
211
Marie Janssen59804562016-12-28 14:13:21 -0800212 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700213 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800214 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
215 Message msg =
216 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700217 mHandler.sendMessage(msg);
218 }
219 };
220
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100221 private final UserRestrictionsListener mUserRestrictionsListener =
222 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800223 @Override
224 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
225 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700226
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800227 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
228 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
229 updateOppLauncherComponentState(userId,
230 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
231 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100232
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800233 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
234 if (userId == UserHandle.USER_SYSTEM
235 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
236 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
237 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
238 UserManager.DISALLOW_BLUETOOTH)) {
239 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800240 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
241 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800242 } else {
243 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
244 UserManager.DISALLOW_BLUETOOTH_SHARING));
245 }
246 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100247 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800248 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100249
Ajay Panicker467bc042017-02-22 12:23:15 -0800250 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
251 @Override
252 public void onChange(boolean unused) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800253 synchronized (this) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800254 if (isBluetoothPersistedStateOn()) {
255 if (isAirplaneModeOn()) {
256 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
257 } else {
258 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
259 }
260 }
261
262 int st = BluetoothAdapter.STATE_OFF;
263 try {
264 mBluetoothLock.readLock().lock();
265 if (mBluetooth != null) {
266 st = mBluetooth.getState();
267 }
268 } catch (RemoteException e) {
269 Slog.e(TAG, "Unable to call getState", e);
270 return;
271 } finally {
272 mBluetoothLock.readLock().unlock();
273 }
274
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800275 Slog.d(TAG,
276 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
277 st));
Ajay Panicker467bc042017-02-22 12:23:15 -0800278
279 if (isAirplaneModeOn()) {
280 // Clear registered LE apps to force shut-off
281 clearBleApps();
282
283 // If state is BLE_ON make sure we trigger disableBLE
284 if (st == BluetoothAdapter.STATE_BLE_ON) {
285 try {
286 mBluetoothLock.readLock().lock();
287 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700288 addActiveLog(
289 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
290 mContext.getPackageName(), false);
Ajay Panicker467bc042017-02-22 12:23:15 -0800291 mBluetooth.onBrEdrDown();
292 mEnable = false;
293 mEnableExternal = false;
294 }
295 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800296 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800297 } finally {
298 mBluetoothLock.readLock().unlock();
299 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800300 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800301 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
302 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800303 }
304 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800305 sendEnableMsg(mQuietEnableExternal,
306 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
307 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800308 }
309 }
310 }
311 };
312
fredcbf072a72012-05-09 16:52:50 -0700313 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700314 @Override
315 public void onReceive(Context context, Intent intent) {
316 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700317 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700318 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800319 if (DBG) {
320 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
321 }
fredc0f420372012-04-12 00:02:00 -0700322 if (newName != null) {
323 storeNameAndAddress(newName, null);
324 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700325 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
326 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
327 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800328 if (DBG) {
329 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
330 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700331 storeNameAndAddress(null, newAddress);
332 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800333 if (DBG) {
334 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
335 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700336 }
Stanley Tng873b5702017-05-01 21:27:31 -0700337 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
338 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
339 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
340 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800341 final String prevValue =
342 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
343 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700344
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800345 if (DBG) {
346 Slog.d(TAG,
347 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
348 + ", newValue=" + newValue);
349 }
Stanley Tng873b5702017-05-01 21:27:31 -0700350
351 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
352 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800353 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
354 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700355 mHandler.sendMessage(msg);
356 }
357 }
fredc0f420372012-04-12 00:02:00 -0700358 }
359 }
360 };
361
362 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700363 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700364
fredc0f420372012-04-12 00:02:00 -0700365 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700366
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800367 mPermissionReviewRequired = context.getResources()
368 .getBoolean(com.android.internal.R.bool.config_permissionReviewRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700369
Marie Janssene54b4222017-03-16 18:10:59 -0700370 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700371 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800372 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800373 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700374 mBinding = false;
375 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700376 mEnable = false;
377 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800378 mQuietEnableExternal = false;
379 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700380 mAddress = null;
381 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800382 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700383 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700384 // Observe BLE scan only mode settings change.
385 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700386 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
387 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700388
389 IntentFilter filter = new IntentFilter();
390 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
391 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
392 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700393 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700394 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700395
fredc0f420372012-04-12 00:02:00 -0700396 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800397 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800398 if (DBG) {
399 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
400 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800401 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700402 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200403
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800404 String airplaneModeRadios =
405 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
406 if (airplaneModeRadios == null || airplaneModeRadios.contains(
407 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800408 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800409 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
410 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800411 }
412
Marie Janssen59804562016-12-28 14:13:21 -0800413 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200414 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800415 // Check if device is configured with no home screen, which implies no SystemUI.
416 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
417 if (!noHome) {
418 systemUiUid = mContext.getPackageManager()
419 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
420 UserHandle.USER_SYSTEM);
421 }
422 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200423 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700424 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700425 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200426 }
Marie Janssen59804562016-12-28 14:13:21 -0800427 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700428 }
429
fredc649fe492012-04-19 01:07:18 -0700430 /**
431 * Returns true if airplane mode is currently on
432 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800433 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700434 return Settings.Global.getInt(mContext.getContentResolver(),
435 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700436 }
437
Arthur Hsu2433baf2018-01-11 11:05:11 -0800438 private boolean supportBluetoothPersistedState() {
439 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
440 }
441
fredc649fe492012-04-19 01:07:18 -0700442 /**
443 * Returns true if the Bluetooth saved state is "on"
444 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800445 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800446 if (!supportBluetoothPersistedState()) {
447 return false;
448 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800449 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
450 if (DBG) {
451 Slog.d(TAG, "Bluetooth persisted state: " + state);
452 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700453 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800454 }
455
456 /**
457 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
458 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800459 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800460 if (!supportBluetoothPersistedState()) {
461 return false;
462 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800463 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
464 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700465 }
466
467 /**
468 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700469 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800470 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800471 if (DBG) {
472 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
473 }
Marie Janssenfa630682016-12-15 13:51:30 -0800474 // waive WRITE_SECURE_SETTINGS permission check
475 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800476 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800477 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700478 }
479
480 /**
481 * Returns true if the Bluetooth Adapter's name and address is
482 * locally cached
483 * @return
484 */
fredc0f420372012-04-12 00:02:00 -0700485 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800486 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700487 }
488
fredc649fe492012-04-19 01:07:18 -0700489 /**
490 * Retrieve the Bluetooth Adapter's name and address and save it in
491 * in the local cache
492 */
fredc0f420372012-04-12 00:02:00 -0700493 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800494 if (DBG) {
495 Slog.d(TAG, "Loading stored name and address");
496 }
497 if (mContext.getResources()
498 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
499 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
500 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700501 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800502 if (DBG) {
503 Slog.d(TAG, "invalid bluetooth name and address stored");
504 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700505 return;
506 }
fredc0f420372012-04-12 00:02:00 -0700507 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
508 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800509 if (DBG) {
510 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
511 }
fredc0f420372012-04-12 00:02:00 -0700512 }
513
fredc649fe492012-04-19 01:07:18 -0700514 /**
515 * Save the Bluetooth name and address in the persistent store.
516 * Only non-null values will be saved.
517 * @param name
518 * @param address
519 */
fredc0f420372012-04-12 00:02:00 -0700520 private void storeNameAndAddress(String name, String address) {
521 if (name != null) {
522 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700523 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800524 if (DBG) {
525 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
526 SECURE_SETTINGS_BLUETOOTH_NAME));
527 }
fredc0f420372012-04-12 00:02:00 -0700528 }
529
530 if (address != null) {
531 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800532 mAddress = address;
533 if (DBG) {
534 Slog.d(TAG,
535 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
536 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
537 }
fredc0f420372012-04-12 00:02:00 -0700538 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700539
540 if ((name != null) && (address != null)) {
541 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
542 }
fredc0f420372012-04-12 00:02:00 -0700543 }
544
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800545 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700546 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700547 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700548 return null;
549 }
fredc0f420372012-04-12 00:02:00 -0700550 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
551 msg.obj = callback;
552 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700553
554 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700555 }
556
557 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700558 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700559 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700560 return;
561 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800562 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700563 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
564 msg.obj = callback;
565 mHandler.sendMessage(msg);
566 }
567
568 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800569 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800570 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800571 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
572 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800573 }
fredc0f420372012-04-12 00:02:00 -0700574 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
575 msg.obj = callback;
576 mHandler.sendMessage(msg);
577 }
578
579 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800580 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800581 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800582 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
583 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800584 }
fredc0f420372012-04-12 00:02:00 -0700585 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
586 msg.obj = callback;
587 mHandler.sendMessage(msg);
588 }
589
590 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800591 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
592 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700593 return false;
594 }
595
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700596 try {
597 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800598 if (mBluetooth != null) {
599 return mBluetooth.isEnabled();
600 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700601 } catch (RemoteException e) {
602 Slog.e(TAG, "isEnabled()", e);
603 } finally {
604 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700605 }
606 return false;
607 }
608
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700609 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800610 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800611 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700612 return BluetoothAdapter.STATE_OFF;
613 }
614
615 try {
616 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800617 if (mBluetooth != null) {
618 return mBluetooth.getState();
619 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700620 } catch (RemoteException e) {
621 Slog.e(TAG, "getState()", e);
622 } finally {
623 mBluetoothLock.readLock().unlock();
624 }
625 return BluetoothAdapter.STATE_OFF;
626 }
627
Nitin Arorad055adb2015-03-02 15:03:51 -0800628 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800629 private String mPackageName;
630
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800631 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800632 mPackageName = packageName;
633 }
634
Nitin Arorad055adb2015-03-02 15:03:51 -0800635 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800636 if (DBG) {
637 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800638 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700639
640 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
641 IBinder token = entry.getKey();
642 ClientDeathRecipient deathRec = entry.getValue();
643 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700644 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700645 break;
646 }
647 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800648 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800649
Marie Janssen59804562016-12-28 14:13:21 -0800650 public String getPackageName() {
651 return mPackageName;
652 }
653 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800654
Wei Wang67d84162015-04-26 17:04:29 -0700655 @Override
656 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700657 if (isAirplaneModeOn() && !mEnable) {
658 return false;
659 }
Wei Wang67d84162015-04-26 17:04:29 -0700660 try {
Jack He8caab152018-03-02 13:08:36 -0800661 return Settings.Global.getInt(mContentResolver,
662 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700663 } catch (SettingNotFoundException e) {
664 }
665 return false;
666 }
667
Wei Wange4a744b2015-06-11 17:50:29 -0700668 // Monitor change of BLE scan only mode settings.
669 private void registerForBleScanModeChange() {
670 ContentObserver contentObserver = new ContentObserver(null) {
671 @Override
672 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800673 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800674 // Nothing to do
675 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800676 }
677 // BLE scan is not available.
678 disableBleScanMode();
679 clearBleApps();
680 try {
681 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800682 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700683 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
684 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800685 mBluetooth.onBrEdrDown();
686 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800687 } catch (RemoteException e) {
688 Slog.e(TAG, "error when disabling bluetooth", e);
689 } finally {
690 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700691 }
692 }
693 };
694
695 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800696 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
697 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700698 }
699
700 // Disable ble scan only mode.
701 private void disableBleScanMode() {
702 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700703 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700704 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800705 if (DBG) {
706 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
707 }
Wei Wange4a744b2015-06-11 17:50:29 -0700708 mEnable = false;
709 }
710 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700711 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700712 } finally {
713 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700714 }
715 }
716
Marie Janssen59804562016-12-28 14:13:21 -0800717 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
718 ClientDeathRecipient r = mBleApps.get(token);
719 if (r == null && enable) {
720 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
721 try {
722 token.linkToDeath(deathRec, 0);
723 } catch (RemoteException ex) {
724 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800725 }
Marie Janssen59804562016-12-28 14:13:21 -0800726 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800727 if (DBG) {
728 Slog.d(TAG, "Registered for death of " + packageName);
729 }
Marie Janssen59804562016-12-28 14:13:21 -0800730 } else if (!enable && r != null) {
731 // Unregister death recipient as the app goes away.
732 token.unlinkToDeath(r, 0);
733 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800734 if (DBG) {
735 Slog.d(TAG, "Unregistered for death of " + packageName);
736 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800737 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800738 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800739 if (DBG) {
740 Slog.d(TAG, appCount + " registered Ble Apps");
741 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800742 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700743 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800744 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800745 if (appCount == 0 && !mEnableExternal) {
746 sendBrEdrDownCallback();
747 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800748 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800749 }
750
Wei Wange4a744b2015-06-11 17:50:29 -0700751 // Clear all apps using BLE scan only mode.
752 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800753 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700754 }
755
Marie Janssen59804562016-12-28 14:13:21 -0800756 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800757 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800758 if (DBG) {
759 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
760 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800761 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800762 }
763
764 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700765 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800766 */
Myles Watson304ebf22018-05-11 08:47:24 -0700767 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800768 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700769 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800770 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700771 try {
772 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800773 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700774 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800775 return;
776 }
777 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
778 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800779 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800780 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800781 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700782 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800783 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700784 } finally {
785 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800786 }
787 }
788
789 /**
790 * Inform BluetoothAdapter instances that BREDR part is down
791 * and turn off all service and stack if no LE app needs it
792 */
793 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800794 if (DBG) {
795 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
796 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700797
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700798 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700799 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700800 return;
801 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800802
Martin Brabhamc2b06222017-02-27 16:55:07 -0800803 if (isBleAppPresent()) {
804 // Need to stay at BLE ON. Disconnect all Gatt connections
805 try {
806 mBluetoothGatt.unregAll();
807 } catch (RemoteException e) {
808 Slog.e(TAG, "Unable to disconnect all apps.", e);
809 }
810 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800811 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700812 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800813 if (mBluetooth != null) {
814 mBluetooth.onBrEdrDown();
815 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700816 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700817 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700818 } finally {
819 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800820 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800821 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800822
Nitin Arorad055adb2015-03-02 15:03:51 -0800823 }
824
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800825 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100826 if (isBluetoothDisallowed()) {
827 if (DBG) {
828 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
829 }
830 return false;
831 }
832
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700833 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800834 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700835
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700836 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800837 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
838 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700839 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800840 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
841
842 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700843 throw new SecurityException("no permission to enable Bluetooth quietly");
844 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800845
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800846 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800847 mQuietEnableExternal = true;
848 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800849 sendEnableMsg(true,
850 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800851 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700852 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700853 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700854
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700855 public boolean enable(String packageName) throws RemoteException {
856 final int callingUid = Binder.getCallingUid();
857 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
858
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100859 if (isBluetoothDisallowed()) {
860 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800861 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100862 }
863 return false;
864 }
865
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700866 if (!callerSystem) {
867 if (!checkIfCallerIsForegroundUser()) {
868 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
869 return false;
870 }
871
872 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
873 "Need BLUETOOTH ADMIN permission");
874
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800875 if (!isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
876 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700877 return false;
878 }
fredcf2458862012-04-16 15:18:27 -0700879 }
880
Zhihai Xu401202b2012-12-03 11:36:21 -0800881 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800882 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
883 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700884 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800885
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800886 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800887 mQuietEnableExternal = false;
888 mEnableExternal = true;
889 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800890 sendEnableMsg(false,
891 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800892 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800893 if (DBG) {
894 Slog.d(TAG, "enable returning");
895 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800896 return true;
fredc0f420372012-04-12 00:02:00 -0700897 }
898
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700899 public boolean disable(String packageName, boolean persist) throws RemoteException {
900 final int callingUid = Binder.getCallingUid();
901 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700902
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700903 if (!callerSystem) {
904 if (!checkIfCallerIsForegroundUser()) {
905 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
906 return false;
907 }
908
909 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
910 "Need BLUETOOTH ADMIN permission");
911
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800912 if (isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
913 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700914 return false;
915 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700916 }
917
fredcf2458862012-04-16 15:18:27 -0700918 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800919 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700920 }
fredcf2458862012-04-16 15:18:27 -0700921
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800922 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800923 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800924 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800925 }
926 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800927 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
928 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800929 }
fredc0f420372012-04-12 00:02:00 -0700930 return true;
931 }
932
baishengf62d8692018-01-25 18:07:24 +0800933 private boolean startConsentUiIfNeeded(String packageName,
934 int callingUid, String intentAction) throws RemoteException {
935 if (checkBluetoothPermissionWhenPermissionReviewRequired()) {
936 return false;
937 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700938 try {
939 // Validate the package only if we are going to use it
940 ApplicationInfo applicationInfo = mContext.getPackageManager()
941 .getApplicationInfoAsUser(packageName,
942 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
943 UserHandle.getUserId(callingUid));
944 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800945 throw new SecurityException("Package " + packageName
946 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700947 }
948
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000949 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000950 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800951 intent.setFlags(
952 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000953 try {
954 mContext.startActivity(intent);
955 } catch (ActivityNotFoundException e) {
956 // Shouldn't happen
957 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
958 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700959 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000960 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700961 } catch (PackageManager.NameNotFoundException e) {
962 throw new RemoteException(e.getMessage());
963 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700964 }
965
baishengf62d8692018-01-25 18:07:24 +0800966 /**
967 * Check if the caller must still pass permission check or if the caller is exempted
968 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED check.
969 *
970 * Commands from some callers may be exempted from triggering the consent UI when
971 * enabling bluetooth. This exemption is checked via the
972 * MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED and allows calls to skip
973 * the consent UI where it may otherwise be required.
974 *
975 * @hide
976 */
977 private boolean checkBluetoothPermissionWhenPermissionReviewRequired() {
978 if (!mPermissionReviewRequired) {
979 return false;
980 }
981 int result = mContext.checkCallingPermission(
982 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED);
983 return result == PackageManager.PERMISSION_GRANTED;
984 }
985
fredc649fe492012-04-19 01:07:18 -0700986 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700987 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800988 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
989 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -0700990 }
991
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700992 try {
993 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800994 if (mUnbinding) {
995 return;
996 }
fredc0f420372012-04-12 00:02:00 -0700997 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -0700998 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -0700999 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001000 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001001 //Unregister callback object
1002 try {
1003 mBluetooth.unregisterCallback(mBluetoothCallback);
1004 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001005 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001006 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001007 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001008 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001009 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001010 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001011 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001012 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001013 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001014 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001015 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001016 } finally {
1017 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001018 }
1019 }
1020
Matthew Xieddf7e472013-03-01 18:41:02 -08001021 public IBluetoothGatt getBluetoothGatt() {
1022 // sync protection
1023 return mBluetoothGatt;
1024 }
1025
Benjamin Franze8b98922014-11-12 15:57:54 +00001026 @Override
1027 public boolean bindBluetoothProfileService(int bluetoothProfile,
1028 IBluetoothProfileServiceConnection proxy) {
1029 if (!mEnable) {
1030 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001031 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1032 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001033 }
1034 return false;
1035 }
1036 synchronized (mProfileServices) {
1037 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1038 if (psc == null) {
1039 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001040 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1041 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001042 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001043
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001044 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1045 return false;
1046 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001047
1048 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001049 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001050 if (!psc.bindService()) {
1051 return false;
1052 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001053
Benjamin Franze8b98922014-11-12 15:57:54 +00001054 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001055 }
1056 }
1057
1058 // Introducing a delay to give the client app time to prepare
1059 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1060 addProxyMsg.arg1 = bluetoothProfile;
1061 addProxyMsg.obj = proxy;
1062 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1063 return true;
1064 }
1065
1066 @Override
1067 public void unbindBluetoothProfileService(int bluetoothProfile,
1068 IBluetoothProfileServiceConnection proxy) {
1069 synchronized (mProfileServices) {
1070 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1071 if (psc == null) {
1072 return;
1073 }
1074 psc.removeProxy(proxy);
1075 }
1076 }
1077
1078 private void unbindAllBluetoothProfileServices() {
1079 synchronized (mProfileServices) {
1080 for (Integer i : mProfileServices.keySet()) {
1081 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001082 try {
1083 mContext.unbindService(psc);
1084 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001085 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001086 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001087 psc.removeAllProxies();
1088 }
1089 mProfileServices.clear();
1090 }
1091 }
1092
1093 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001094 * Send enable message and set adapter name and address. Called when the boot phase becomes
1095 * PHASE_SYSTEM_SERVICES_READY.
1096 */
1097 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001098 if (DBG) {
1099 Slog.d(TAG, "Bluetooth boot completed");
1100 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001101 UserManagerInternal userManagerInternal =
1102 LocalServices.getService(UserManagerInternal.class);
1103 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001104 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001105 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001106 return;
1107 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001108 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001109 if (DBG) {
1110 Slog.d(TAG, "Auto-enabling Bluetooth.");
1111 }
Jack He8caab152018-03-02 13:08:36 -08001112 sendEnableMsg(mQuietEnableExternal,
1113 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1114 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001115 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001116 if (DBG) {
1117 Slog.d(TAG, "Getting adapter name and address");
1118 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001119 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1120 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001121 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001122 }
1123
1124 /**
1125 * Called when switching to a different foreground user.
1126 */
1127 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001128 if (DBG) {
1129 Slog.d(TAG, "User " + userHandle + " switched");
1130 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001131 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1132 }
1133
1134 /**
1135 * Called when user is unlocked.
1136 */
1137 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001138 if (DBG) {
1139 Slog.d(TAG, "User " + userHandle + " unlocked");
1140 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001141 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001142 }
1143
1144 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001145 * This class manages the clients connected to a given ProfileService
1146 * and maintains the connection with that service.
1147 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001148 private final class ProfileServiceConnections
1149 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001150 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001151 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001152 IBinder mService;
1153 ComponentName mClassName;
1154 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001155 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001156
1157 ProfileServiceConnections(Intent intent) {
1158 mService = null;
1159 mClassName = null;
1160 mIntent = intent;
1161 }
1162
Benjamin Franz5b614592014-12-09 18:58:45 +00001163 private boolean bindService() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001164 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1165 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001166 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1167 msg.obj = this;
1168 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001169 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001170 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001171 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001172 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001173 }
1174
1175 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1176 mProxies.register(proxy);
1177 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001178 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001179 proxy.onServiceConnected(mClassName, mService);
1180 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001181 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001182 }
1183 } else {
1184 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1185 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1186 msg.obj = this;
1187 mHandler.sendMessage(msg);
1188 }
1189 }
1190 }
1191
1192 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1193 if (proxy != null) {
1194 if (mProxies.unregister(proxy)) {
1195 try {
1196 proxy.onServiceDisconnected(mClassName);
1197 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001198 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001199 }
1200 }
1201 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001202 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001203 }
1204 }
1205
1206 private void removeAllProxies() {
1207 onServiceDisconnected(mClassName);
1208 mProxies.kill();
1209 }
1210
1211 @Override
1212 public void onServiceConnected(ComponentName className, IBinder service) {
1213 // remove timeout message
1214 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1215 mService = service;
1216 mClassName = className;
1217 try {
1218 mService.linkToDeath(this, 0);
1219 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001220 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001221 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001222
1223 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001224 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001225 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001226 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001227 mInvokingProxyCallbacks = true;
1228
1229 final int n = mProxies.beginBroadcast();
1230 try {
1231 for (int i = 0; i < n; i++) {
1232 try {
1233 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1234 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001235 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001236 }
1237 }
1238 } finally {
1239 mProxies.finishBroadcast();
1240 mInvokingProxyCallbacks = false;
1241 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001242 }
1243
1244 @Override
1245 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001246 if (mService == null) {
1247 return;
1248 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001249 mService.unlinkToDeath(this, 0);
1250 mService = null;
1251 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001252
1253 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001254 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001255 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001256 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001257 mInvokingProxyCallbacks = true;
1258
1259 final int n = mProxies.beginBroadcast();
1260 try {
1261 for (int i = 0; i < n; i++) {
1262 try {
1263 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1264 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001265 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001266 }
1267 }
1268 } finally {
1269 mProxies.finishBroadcast();
1270 mInvokingProxyCallbacks = false;
1271 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001272 }
1273
1274 @Override
1275 public void binderDied() {
1276 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001277 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001278 }
1279 onServiceDisconnected(mClassName);
1280 // Trigger rebind
1281 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1282 msg.obj = this;
1283 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1284 }
1285 }
1286
fredcbf072a72012-05-09 16:52:50 -07001287 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001288 try {
1289 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001290 if (DBG) {
1291 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1292 + " receivers.");
1293 }
1294 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001295 try {
1296 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1297 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001298 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001299 }
fredcbf072a72012-05-09 16:52:50 -07001300 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001301 } finally {
1302 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001303 }
fredcbf072a72012-05-09 16:52:50 -07001304 }
1305
1306 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001307 * Inform BluetoothAdapter instances that Adapter service is up
1308 */
1309 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001310 try {
1311 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001312 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1313 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001314 try {
1315 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001316 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001317 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001318 }
1319 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001320 } finally {
1321 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001322 }
1323 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001324
Zhihai Xu40874a02012-10-08 17:57:03 -07001325 /**
fredcbf072a72012-05-09 16:52:50 -07001326 * Inform BluetoothAdapter instances that Adapter service is down
1327 */
1328 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001329 try {
1330 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001331 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1332 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001333 try {
1334 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001335 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001336 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001337 }
1338 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001339 } finally {
1340 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001341 }
1342 }
Svet Ganov408abf72015-05-12 19:13:36 -07001343
fredc0f420372012-04-12 00:02:00 -07001344 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001345 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001346
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001347 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1348 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001349 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001350 }
1351
Svet Ganov408abf72015-05-12 19:13:36 -07001352 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1353 != PackageManager.PERMISSION_GRANTED) {
1354 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1355 }
1356
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001357 try {
1358 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001359 if (mBluetooth != null) {
1360 return mBluetooth.getAddress();
1361 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001362 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001363 Slog.e(TAG,
1364 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1365 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001366 } finally {
1367 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001368 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001369
Matthew Xiecdce0b92012-07-12 19:06:15 -07001370 // mAddress is accessed from outside.
1371 // It is alright without a lock. Here, bluetooth is off, no other thread is
1372 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001373 return mAddress;
1374 }
fredc649fe492012-04-19 01:07:18 -07001375
fredc0f420372012-04-12 00:02:00 -07001376 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001377 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001378
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001379 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1380 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001381 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001382 }
1383
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001384 try {
1385 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001386 if (mBluetooth != null) {
1387 return mBluetooth.getName();
1388 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001389 } catch (RemoteException e) {
1390 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1391 } finally {
1392 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001393 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001394
Matthew Xiecdce0b92012-07-12 19:06:15 -07001395 // mName is accessed from outside.
1396 // It alright without a lock. Here, bluetooth is off, no other thread is
1397 // changing mName
fredc0f420372012-04-12 00:02:00 -07001398 return mName;
1399 }
1400
fredc0f420372012-04-12 00:02:00 -07001401 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001402 public void onServiceConnected(ComponentName componentName, IBinder service) {
1403 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001404 if (DBG) {
1405 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1406 }
fredc0f420372012-04-12 00:02:00 -07001407 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001408 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001409 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001410 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001411 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1412 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001413 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001414 return;
1415 }
fredc0f420372012-04-12 00:02:00 -07001416 msg.obj = service;
1417 mHandler.sendMessage(msg);
1418 }
1419
Marie Janssencb21ad72016-12-13 10:51:02 -08001420 public void onServiceDisconnected(ComponentName componentName) {
1421 // Called if we unexpectedly disconnect.
1422 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001423 if (DBG) {
1424 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1425 }
fredc0f420372012-04-12 00:02:00 -07001426 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001427 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001428 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001429 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001430 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1431 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001432 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001433 return;
1434 }
fredc0f420372012-04-12 00:02:00 -07001435 mHandler.sendMessage(msg);
1436 }
1437 }
1438
1439 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1440
Zhihai Xu40874a02012-10-08 17:57:03 -07001441 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001442 boolean mGetNameAddressOnly = false;
1443
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001444 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001445 super(looper);
1446 }
1447
fredc0f420372012-04-12 00:02:00 -07001448 @Override
1449 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001450 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001451 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001452 if (DBG) {
1453 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1454 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001455 try {
1456 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001457 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001458 if (DBG) {
1459 Slog.d(TAG, "Binding to service to get name and address");
1460 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001461 mGetNameAddressOnly = true;
1462 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1463 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1464 Intent i = new Intent(IBluetooth.class.getName());
1465 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001466 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1467 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001468 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1469 } else {
1470 mBinding = true;
1471 }
1472 } else if (mBluetooth != null) {
1473 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001474 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001475 } catch (RemoteException re) {
1476 Slog.e(TAG, "Unable to grab names", re);
1477 }
1478 if (mGetNameAddressOnly && !mEnable) {
1479 unbindAndFinish();
1480 }
1481 mGetNameAddressOnly = false;
1482 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001483 } finally {
1484 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001485 }
1486 break;
1487
Matthew Xiecdce0b92012-07-12 19:06:15 -07001488 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001489 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001490 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001491 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001492 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1493 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001494
1495 // Use service interface to get the exact state
1496 try {
1497 mBluetoothLock.readLock().lock();
1498 if (mBluetooth != null) {
1499 int state = mBluetooth.getState();
1500 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001501 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001502 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001503 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001504 break;
1505 }
1506 }
1507 } catch (RemoteException e) {
1508 Slog.e(TAG, "", e);
1509 } finally {
1510 mBluetoothLock.readLock().unlock();
1511 }
1512
1513 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001514 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001515 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001516 } else {
1517 //
1518 // We need to wait until transitioned to STATE_OFF and
1519 // the previous Bluetooth process has exited. The
1520 // waiting period has three components:
1521 // (a) Wait until the local state is STATE_OFF. This
1522 // is accomplished by "waitForOnOff(false, true)".
1523 // (b) Wait until the STATE_OFF state is updated to
1524 // all components.
1525 // (c) Wait until the Bluetooth process exits, and
1526 // ActivityManager detects it.
1527 // The waiting for (b) and (c) is accomplished by
1528 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1529 // message. On slower devices, that delay needs to be
1530 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1531 //
1532 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001533 Message restartMsg =
1534 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1535 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001536 }
fredc649fe492012-04-19 01:07:18 -07001537 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001538
fredc0f420372012-04-12 00:02:00 -07001539 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001540 if (DBG) {
1541 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1542 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001543 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1544 if (mEnable && mBluetooth != null) {
1545 waitForOnOff(true, false);
1546 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001547 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001548 waitForOnOff(false, false);
1549 } else {
1550 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001551 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001552 }
fredc0f420372012-04-12 00:02:00 -07001553 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001554
Stanley Tng873b5702017-05-01 21:27:31 -07001555 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001556 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1557 if (DBG) {
1558 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001559 }
Jack He8caab152018-03-02 13:08:36 -08001560 persistBluetoothSetting(BLUETOOTH_OFF);
1561 mEnableExternal = false;
1562 sendDisableMsg(
1563 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1564 mContext.getPackageName());
1565 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1566 if (DBG) {
1567 Slog.d(TAG, "Restore Bluetooth state to enabled");
1568 }
1569 mQuietEnableExternal = false;
1570 mEnableExternal = true;
1571 // waive WRITE_SECURE_SETTINGS permission check
1572 sendEnableMsg(false,
1573 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1574 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001575 }
1576 break;
1577
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001578 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001579 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001580 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001581 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001582 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001583 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001584 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001585 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001586 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001587 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001588 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1589 IBluetoothStateChangeCallback callback =
1590 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001591 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001592 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001593 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001594 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1595 IBluetoothStateChangeCallback callback =
1596 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001597 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001598 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001599 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001600 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001601 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001602 if (psc == null) {
1603 break;
1604 }
1605 IBluetoothProfileServiceConnection proxy =
1606 (IBluetoothProfileServiceConnection) msg.obj;
1607 psc.addProxy(proxy);
1608 break;
1609 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001610 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001611 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1612 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1613 if (psc == null) {
1614 break;
1615 }
1616 psc.bindService();
1617 break;
1618 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001619 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1620 if (DBG) {
1621 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1622 }
fredc0f420372012-04-12 00:02:00 -07001623
1624 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001625 try {
1626 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001627 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001628 mBluetoothGatt =
1629 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001630 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001631 break;
1632 } // else must be SERVICE_IBLUETOOTH
1633
1634 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001635 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001636
fredc0f420372012-04-12 00:02:00 -07001637 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001638 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001639 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001640
Ajay Panicker4bb48302016-03-31 14:14:27 -07001641 if (!isNameAndAddressSet()) {
1642 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1643 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001644 if (mGetNameAddressOnly) {
1645 return;
1646 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001647 }
1648
Matthew Xiecdce0b92012-07-12 19:06:15 -07001649 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001650 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001651 mBluetooth.registerCallback(mBluetoothCallback);
1652 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001653 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001654 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001655 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001656 sendBluetoothServiceUpCallback();
1657
Matthew Xiecdce0b92012-07-12 19:06:15 -07001658 //Do enable request
1659 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001660 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001661 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001662 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001663 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001664 } else {
1665 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001666 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001667 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001668 }
1669 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001670 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001671 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001672 } finally {
1673 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001674 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001675
1676 if (!mEnable) {
1677 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001678 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001679 waitForOnOff(false, false);
1680 }
fredc649fe492012-04-19 01:07:18 -07001681 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001682 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001683 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001684 int prevState = msg.arg1;
1685 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001686 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001687 Slog.d(TAG,
1688 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1689 prevState) + " > " + BluetoothAdapter.nameForState(
1690 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001691 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001692 mState = newState;
1693 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001694 // handle error state transition case from TURNING_ON to OFF
1695 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001696 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1697 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001698 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001699 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001700 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1701 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001702 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001703 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001704 // If we tried to enable BT while BT was in the process of shutting down,
1705 // wait for the BT process to fully tear down and then force a restart
1706 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001707 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1708 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001709 if (mEnable) {
1710 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1711 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001712 Message restartMsg =
1713 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001714 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1715 }
1716 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001717 if (newState == BluetoothAdapter.STATE_ON
1718 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001719 // bluetooth is working, reset the counter
1720 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001721 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001722 mErrorRecoveryRetryCounter = 0;
1723 }
1724 }
fredc649fe492012-04-19 01:07:18 -07001725 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001726 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001727 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001728 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001729 try {
1730 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001731 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1732 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001733 if (mBluetooth == null) {
1734 break;
1735 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001736 mBluetooth = null;
1737 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1738 mBluetoothGatt = null;
1739 break;
1740 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001741 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001742 break;
1743 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001744 } finally {
1745 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301746 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001747
Marie Janssene54b4222017-03-16 18:10:59 -07001748 // log the unexpected crash
1749 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001750 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1751 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001752 if (mEnable) {
1753 mEnable = false;
1754 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001755 Message restartMsg =
1756 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1757 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001758 }
1759
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001760 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001761
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001762 // Send BT state broadcast to update
1763 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001764 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1765 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001766 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001767 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001768 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001769 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001770 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1771 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001772 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001773 }
1774
1775 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1776 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001777 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001778 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001779 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001780 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301781 /* Enable without persisting the setting as
1782 it doesnt change when IBluetooth
1783 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001784 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001785 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1786 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001787 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301788 break;
1789 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001790 case MESSAGE_TIMEOUT_BIND: {
1791 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1792 mBluetoothLock.writeLock().lock();
1793 mBinding = false;
1794 mBluetoothLock.writeLock().unlock();
1795 break;
1796 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001797 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001798 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001799 mBluetoothLock.writeLock().lock();
1800 mUnbinding = false;
1801 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001802 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001803 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001804
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001805 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001806 if (DBG) {
1807 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1808 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001809 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001810
Zhihai Xu40874a02012-10-08 17:57:03 -07001811 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001812 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001813 try {
1814 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001815 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001816 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001817 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001818 } catch (RemoteException re) {
1819 Slog.e(TAG, "Unable to unregister", re);
1820 } finally {
1821 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001822 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001823
1824 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1825 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1826 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1827 mState = BluetoothAdapter.STATE_OFF;
1828 }
1829 if (mState == BluetoothAdapter.STATE_OFF) {
1830 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1831 mState = BluetoothAdapter.STATE_TURNING_ON;
1832 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001833
1834 waitForOnOff(true, false);
1835
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001836 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1837 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1838 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001839
Benjamin Franze8b98922014-11-12 15:57:54 +00001840 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001841 // disable
Jack He8caab152018-03-02 13:08:36 -08001842 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1843 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001844 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001845 // Pbap service need receive STATE_TURNING_OFF intent to close
1846 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001847 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001848
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001849 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001850
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001851 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001852 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001853 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001854
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001855 try {
1856 mBluetoothLock.writeLock().lock();
1857 if (mBluetooth != null) {
1858 mBluetooth = null;
1859 // Unbind
1860 mContext.unbindService(mConnection);
1861 }
1862 mBluetoothGatt = null;
1863 } finally {
1864 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001865 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001866
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001867 //
1868 // If disabling Bluetooth times out, wait for an
1869 // additional amount of time to ensure the process is
1870 // shut down completely before attempting to restart.
1871 //
1872 if (didDisableTimeout) {
1873 SystemClock.sleep(3000);
1874 } else {
1875 SystemClock.sleep(100);
1876 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001877
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001878 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1879 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001880 // enable
Jack He8caab152018-03-02 13:08:36 -08001881 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1882 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001883 // mEnable flag could have been reset on disableBLE. Reenable it.
1884 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001885 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001886 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001887 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1888 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001889 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001890 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1891 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001892 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001893 }
John Spurlock8a985d22014-02-25 09:40:05 -05001894 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001895 break;
1896 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001897 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001898 if (DBG) {
1899 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1900 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001901 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1902
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001903 if (mEnable && !mBinding && (mBluetooth == null)) {
1904 // We should be connected, but we gave up for some
1905 // reason; maybe the Bluetooth service wasn't encryption
1906 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001907 if (DBG) {
1908 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1909 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001910 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001911 }
1912 }
fredc0f420372012-04-12 00:02:00 -07001913 }
1914 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001915 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001916
Zhihai Xu401202b2012-12-03 11:36:21 -08001917 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001918 mQuietEnable = quietMode;
1919
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001920 try {
1921 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001922 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001923 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001924 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1925 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001926 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001927 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001928 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001929 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001930 } else {
1931 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001932 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001933 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001934 //Enable bluetooth
1935 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001936 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001937 if (!mBluetooth.enable()) {
1938 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001939 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001940 } else {
1941 if (!mBluetooth.enableNoAutoConnect()) {
1942 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001943 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001944 }
1945 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001946 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001947 }
1948 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001949 } finally {
1950 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001951 }
1952 }
1953
Dianne Hackborn221ea892013-08-04 16:50:16 -07001954 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1955 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1956 intent.setComponent(comp);
1957 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001958 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001959 return false;
1960 }
1961 return true;
1962 }
1963
Zhihai Xu401202b2012-12-03 11:36:21 -08001964 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001965 try {
1966 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001967 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001968 if (DBG) {
1969 Slog.d(TAG, "Sending off request.");
1970 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001971 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001972 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001973 }
1974 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001975 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001976 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001977 } finally {
1978 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001979 }
1980 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001981
1982 private boolean checkIfCallerIsForegroundUser() {
1983 int foregroundUser;
1984 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001985 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07001986 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00001987 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1988 UserInfo ui = um.getProfileParent(callingUser);
1989 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001990 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07001991 boolean valid = false;
1992 try {
1993 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001994 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
1995 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08001996 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001997 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
1998 + callingUser + " parentUser=" + parentUser + " foregroundUser="
1999 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002000 }
2001 } finally {
2002 Binder.restoreCallingIdentity(callingIdentity);
2003 }
2004 return valid;
2005 }
2006
Nitin Arorad055adb2015-03-02 15:03:51 -08002007 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002008 if (DBG) {
2009 Slog.d(TAG,
2010 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2011 + BluetoothAdapter.nameForState(newState));
2012 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002013 // Send broadcast message to everyone else
2014 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2015 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2016 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2017 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2018 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2019 }
2020
Zhihai Xu40874a02012-10-08 17:57:03 -07002021 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002022 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002023 if (prevState == newState) { // No change. Nothing to do.
2024 return;
2025 }
2026 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002027 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002028 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002029 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002030
Marie Janssencb21ad72016-12-13 10:51:02 -08002031 if (newState == BluetoothAdapter.STATE_OFF) {
2032 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002033 if (DBG) {
2034 Slog.d(TAG, "Bluetooth is complete send Service Down");
2035 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002036 sendBluetoothServiceDownCallback();
2037 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002038 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002039 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002040 isStandardBroadcast = false;
2041
Marie Janssencb21ad72016-12-13 10:51:02 -08002042 } else if (!intermediate_off) {
2043 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002044 if (DBG) {
2045 Slog.d(TAG, "Bluetooth is in LE only mode");
2046 }
Myles Watson304ebf22018-05-11 08:47:24 -07002047 if (mBluetoothGatt != null || !mContext.getPackageManager()
2048 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2049 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002050 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002051 if (DBG) {
2052 Slog.d(TAG, "Binding Bluetooth GATT service");
2053 }
Myles Watson304ebf22018-05-11 08:47:24 -07002054 Intent i = new Intent(IBluetoothGatt.class.getName());
2055 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2056 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002057 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002058 sendBleStateChanged(prevState, newState);
2059 //Don't broadcase this as std intent
2060 isStandardBroadcast = false;
2061
2062 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002063 if (DBG) {
2064 Slog.d(TAG, "Intermediate off, back to LE only mode");
2065 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002066 // For LE only mode, broadcast as is
2067 sendBleStateChanged(prevState, newState);
2068 sendBluetoothStateCallback(false); // BT is OFF for general users
2069 // Broadcast as STATE_OFF
2070 newState = BluetoothAdapter.STATE_OFF;
2071 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002072 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002073 } else if (newState == BluetoothAdapter.STATE_ON) {
2074 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2075 sendBluetoothStateCallback(isUp);
2076 sendBleStateChanged(prevState, newState);
2077
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002078 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2079 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002080 sendBleStateChanged(prevState, newState);
2081 isStandardBroadcast = false;
2082
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002083 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2084 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002085 sendBleStateChanged(prevState, newState);
2086 }
2087
2088 if (isStandardBroadcast) {
2089 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2090 // Show prevState of BLE_ON as OFF to standard users
2091 prevState = BluetoothAdapter.STATE_OFF;
2092 }
2093 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2094 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2095 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2096 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2097 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002098 }
2099 }
2100
2101 /**
2102 * if on is true, wait for state become ON
2103 * if off is true, wait for state become OFF
2104 * if both on and off are false, wait for state not ON
2105 */
2106 private boolean waitForOnOff(boolean on, boolean off) {
2107 int i = 0;
2108 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002109 try {
2110 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002111 if (mBluetooth == null) {
2112 break;
2113 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002114 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002115 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2116 return true;
2117 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002118 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002119 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2120 return true;
2121 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002122 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002123 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2124 return true;
2125 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002126 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002127 } catch (RemoteException e) {
2128 Slog.e(TAG, "getState()", e);
2129 break;
2130 } finally {
2131 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002132 }
2133 if (on || off) {
2134 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002135 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002136 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002137 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002138 i++;
2139 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002140 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002141 return false;
2142 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002143
Jack He8caab152018-03-02 13:08:36 -08002144 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002145 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002146 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002147 }
2148
Jack He8caab152018-03-02 13:08:36 -08002149 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002150 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002151 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002152 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002153 }
2154
Jack He8caab152018-03-02 13:08:36 -08002155 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002156 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002157 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002158 mActiveLogs.remove();
2159 }
Jack He8caab152018-03-02 13:08:36 -08002160 mActiveLogs.add(
2161 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002162 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002163
2164 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2165 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2166 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2167 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002168 }
2169
Marie Janssene54b4222017-03-16 18:10:59 -07002170 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002171 synchronized (mCrashTimestamps) {
2172 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2173 mCrashTimestamps.removeFirst();
2174 }
2175 mCrashTimestamps.add(System.currentTimeMillis());
2176 mCrashes++;
2177 }
Marie Janssene54b4222017-03-16 18:10:59 -07002178 }
2179
Marie Janssen2977c3e2016-11-09 12:01:24 -08002180 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002181 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002182 try {
2183 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002184 if (mBluetooth != null) {
2185 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002186 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002187 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002188 } catch (RemoteException re) {
2189 Slog.e(TAG, "Unable to unregister", re);
2190 } finally {
2191 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002192 }
2193
2194 SystemClock.sleep(500);
2195
2196 // disable
Jack He8caab152018-03-02 13:08:36 -08002197 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2198 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002199 handleDisable();
2200
2201 waitForOnOff(false, true);
2202
2203 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002204
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002205 try {
2206 mBluetoothLock.writeLock().lock();
2207 if (mBluetooth != null) {
2208 mBluetooth = null;
2209 // Unbind
2210 mContext.unbindService(mConnection);
2211 }
2212 mBluetoothGatt = null;
2213 } finally {
2214 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002215 }
2216
2217 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2218 mState = BluetoothAdapter.STATE_OFF;
2219
Marie Janssen2977c3e2016-11-09 12:01:24 -08002220 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002221 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002222 }
2223
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002224 mEnable = false;
2225
2226 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2227 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002228 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002229 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2230 } else {
2231 // todo: notify user to power down and power up phone to make bluetooth work.
2232 }
2233 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002234
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002235 private boolean isBluetoothDisallowed() {
2236 long callingIdentity = Binder.clearCallingIdentity();
2237 try {
2238 return mContext.getSystemService(UserManager.class)
2239 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2240 } finally {
2241 Binder.restoreCallingIdentity(callingIdentity);
2242 }
2243 }
2244
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002245 /**
2246 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002247 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2248 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002249 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002250 * @param userId user to disable bluetooth sharing for.
2251 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002252 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002253 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002254 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2255 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002256 final int newState =
2257 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2258 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002259 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002260 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002261 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2262 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002263 } catch (Exception e) {
2264 // The component was not found, do nothing.
2265 }
2266 }
2267
Mike Lockwood726d4de2014-10-28 14:06:28 -07002268 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002269 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002270 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2271 return;
2272 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002273 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002274
2275 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2276
2277 if (!protoOut) {
2278 writer.println("Bluetooth Status");
2279 writer.println(" enabled: " + isEnabled());
2280 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2281 writer.println(" address: " + mAddress);
2282 writer.println(" name: " + mName);
2283 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002284 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002285 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2286 (int) (onDuration / (1000 * 60 * 60)),
2287 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2288 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002289 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002290 }
2291
Marie Janssena95924d2017-01-18 09:37:52 -08002292 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002293 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002294 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002295 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002296 for (ActiveLog log : mActiveLogs) {
2297 writer.println(" " + log);
2298 }
Marie Janssen59804562016-12-28 14:13:21 -08002299 }
2300
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002301 writer.println(
2302 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2303 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2304 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2305 }
Marie Janssene54b4222017-03-16 18:10:59 -07002306 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002307 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002308 }
2309
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002310 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2311 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002312 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002313 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002314 }
2315
Marie Janssena95924d2017-01-18 09:37:52 -08002316 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002317 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002318 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002319 // Add arg to produce output
2320 args = new String[1];
2321 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002322 }
Marie Janssen59804562016-12-28 14:13:21 -08002323 }
2324
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002325 if (mBluetoothBinder == null) {
2326 errorMsg = "Bluetooth Service not connected";
2327 } else {
2328 try {
2329 mBluetoothBinder.dump(fd, args);
2330 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002331 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002332 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002333 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002334 if (errorMsg != null) {
2335 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002336 if (protoOut) {
2337 return;
2338 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002339 writer.println(errorMsg);
2340 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002341 }
Jack He8caab152018-03-02 13:08:36 -08002342
2343 private static String getEnableDisableReasonString(int reason) {
2344 switch (reason) {
2345 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2346 return "APPLICATION_REQUEST";
2347 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2348 return "AIRPLANE_MODE";
2349 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2350 return "DISALLOWED";
2351 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2352 return "RESTARTED";
2353 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2354 return "START_ERROR";
2355 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2356 return "SYSTEM_BOOT";
2357 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2358 return "CRASH";
2359 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2360 return "USER_SWITCH";
2361 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2362 return "RESTORE_USER_SETTING";
2363 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2364 default: return "UNKNOWN[" + reason + "]";
2365 }
2366 }
fredc0f420372012-04-12 00:02:00 -07002367}