blob: 8d10cfaaf9c096e39b2a176974b6d1ec32520dd2 [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) {
288 mBluetooth.onBrEdrDown();
289 mEnable = false;
290 mEnableExternal = false;
291 }
292 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800293 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800294 } finally {
295 mBluetoothLock.readLock().unlock();
296 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800297 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800298 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
299 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800300 }
301 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800302 sendEnableMsg(mQuietEnableExternal,
303 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
304 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800305 }
306 }
307 }
308 };
309
fredcbf072a72012-05-09 16:52:50 -0700310 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700311 @Override
312 public void onReceive(Context context, Intent intent) {
313 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700314 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700315 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800316 if (DBG) {
317 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
318 }
fredc0f420372012-04-12 00:02:00 -0700319 if (newName != null) {
320 storeNameAndAddress(newName, null);
321 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700322 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
323 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
324 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800325 if (DBG) {
326 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
327 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700328 storeNameAndAddress(null, newAddress);
329 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800330 if (DBG) {
331 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
332 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700333 }
Stanley Tng873b5702017-05-01 21:27:31 -0700334 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
335 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
336 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
337 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800338 final String prevValue =
339 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
340 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700341
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800342 if (DBG) {
343 Slog.d(TAG,
344 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
345 + ", newValue=" + newValue);
346 }
Stanley Tng873b5702017-05-01 21:27:31 -0700347
348 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
349 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800350 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
351 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700352 mHandler.sendMessage(msg);
353 }
354 }
fredc0f420372012-04-12 00:02:00 -0700355 }
356 }
357 };
358
359 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700360 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700361
fredc0f420372012-04-12 00:02:00 -0700362 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700363
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800364 mPermissionReviewRequired = context.getResources()
365 .getBoolean(com.android.internal.R.bool.config_permissionReviewRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700366
Marie Janssene54b4222017-03-16 18:10:59 -0700367 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700368 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800369 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800370 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700371 mBinding = false;
372 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700373 mEnable = false;
374 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800375 mQuietEnableExternal = false;
376 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700377 mAddress = null;
378 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800379 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700380 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700381 // Observe BLE scan only mode settings change.
382 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700383 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
384 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700385
386 IntentFilter filter = new IntentFilter();
387 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
388 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
389 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700390 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700391 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700392
fredc0f420372012-04-12 00:02:00 -0700393 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800394 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800395 if (DBG) {
396 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
397 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800398 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700399 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200400
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800401 String airplaneModeRadios =
402 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
403 if (airplaneModeRadios == null || airplaneModeRadios.contains(
404 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800405 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800406 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
407 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800408 }
409
Marie Janssen59804562016-12-28 14:13:21 -0800410 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200411 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800412 // Check if device is configured with no home screen, which implies no SystemUI.
413 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
414 if (!noHome) {
415 systemUiUid = mContext.getPackageManager()
416 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
417 UserHandle.USER_SYSTEM);
418 }
419 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200420 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700421 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700422 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200423 }
Marie Janssen59804562016-12-28 14:13:21 -0800424 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700425 }
426
fredc649fe492012-04-19 01:07:18 -0700427 /**
428 * Returns true if airplane mode is currently on
429 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800430 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700431 return Settings.Global.getInt(mContext.getContentResolver(),
432 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700433 }
434
Arthur Hsu2433baf2018-01-11 11:05:11 -0800435 private boolean supportBluetoothPersistedState() {
436 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
437 }
438
fredc649fe492012-04-19 01:07:18 -0700439 /**
440 * Returns true if the Bluetooth saved state is "on"
441 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800442 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800443 if (!supportBluetoothPersistedState()) {
444 return false;
445 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800446 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
447 if (DBG) {
448 Slog.d(TAG, "Bluetooth persisted state: " + state);
449 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700450 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800451 }
452
453 /**
454 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
455 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800456 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800457 if (!supportBluetoothPersistedState()) {
458 return false;
459 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800460 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
461 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700462 }
463
464 /**
465 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700466 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800467 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800468 if (DBG) {
469 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
470 }
Marie Janssenfa630682016-12-15 13:51:30 -0800471 // waive WRITE_SECURE_SETTINGS permission check
472 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800473 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800474 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700475 }
476
477 /**
478 * Returns true if the Bluetooth Adapter's name and address is
479 * locally cached
480 * @return
481 */
fredc0f420372012-04-12 00:02:00 -0700482 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800483 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700484 }
485
fredc649fe492012-04-19 01:07:18 -0700486 /**
487 * Retrieve the Bluetooth Adapter's name and address and save it in
488 * in the local cache
489 */
fredc0f420372012-04-12 00:02:00 -0700490 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800491 if (DBG) {
492 Slog.d(TAG, "Loading stored name and address");
493 }
494 if (mContext.getResources()
495 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
496 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
497 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700498 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800499 if (DBG) {
500 Slog.d(TAG, "invalid bluetooth name and address stored");
501 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700502 return;
503 }
fredc0f420372012-04-12 00:02:00 -0700504 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
505 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800506 if (DBG) {
507 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
508 }
fredc0f420372012-04-12 00:02:00 -0700509 }
510
fredc649fe492012-04-19 01:07:18 -0700511 /**
512 * Save the Bluetooth name and address in the persistent store.
513 * Only non-null values will be saved.
514 * @param name
515 * @param address
516 */
fredc0f420372012-04-12 00:02:00 -0700517 private void storeNameAndAddress(String name, String address) {
518 if (name != null) {
519 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700520 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800521 if (DBG) {
522 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
523 SECURE_SETTINGS_BLUETOOTH_NAME));
524 }
fredc0f420372012-04-12 00:02:00 -0700525 }
526
527 if (address != null) {
528 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800529 mAddress = address;
530 if (DBG) {
531 Slog.d(TAG,
532 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
533 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
534 }
fredc0f420372012-04-12 00:02:00 -0700535 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700536
537 if ((name != null) && (address != null)) {
538 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
539 }
fredc0f420372012-04-12 00:02:00 -0700540 }
541
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800542 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700543 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700544 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700545 return null;
546 }
fredc0f420372012-04-12 00:02:00 -0700547 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
548 msg.obj = callback;
549 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700550
551 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700552 }
553
554 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700555 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700556 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700557 return;
558 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800559 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700560 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
561 msg.obj = callback;
562 mHandler.sendMessage(msg);
563 }
564
565 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800566 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800567 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800568 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
569 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800570 }
fredc0f420372012-04-12 00:02:00 -0700571 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
572 msg.obj = callback;
573 mHandler.sendMessage(msg);
574 }
575
576 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800577 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800578 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800579 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
580 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800581 }
fredc0f420372012-04-12 00:02:00 -0700582 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
583 msg.obj = callback;
584 mHandler.sendMessage(msg);
585 }
586
587 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800588 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
589 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700590 return false;
591 }
592
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700593 try {
594 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800595 if (mBluetooth != null) {
596 return mBluetooth.isEnabled();
597 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700598 } catch (RemoteException e) {
599 Slog.e(TAG, "isEnabled()", e);
600 } finally {
601 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700602 }
603 return false;
604 }
605
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700606 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800607 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800608 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700609 return BluetoothAdapter.STATE_OFF;
610 }
611
612 try {
613 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800614 if (mBluetooth != null) {
615 return mBluetooth.getState();
616 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700617 } catch (RemoteException e) {
618 Slog.e(TAG, "getState()", e);
619 } finally {
620 mBluetoothLock.readLock().unlock();
621 }
622 return BluetoothAdapter.STATE_OFF;
623 }
624
Nitin Arorad055adb2015-03-02 15:03:51 -0800625 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800626 private String mPackageName;
627
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800628 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800629 mPackageName = packageName;
630 }
631
Nitin Arorad055adb2015-03-02 15:03:51 -0800632 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800633 if (DBG) {
634 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800635 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700636
637 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
638 IBinder token = entry.getKey();
639 ClientDeathRecipient deathRec = entry.getValue();
640 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700641 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700642 break;
643 }
644 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800645 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800646
Marie Janssen59804562016-12-28 14:13:21 -0800647 public String getPackageName() {
648 return mPackageName;
649 }
650 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800651
Wei Wang67d84162015-04-26 17:04:29 -0700652 @Override
653 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700654 if (isAirplaneModeOn() && !mEnable) {
655 return false;
656 }
Wei Wang67d84162015-04-26 17:04:29 -0700657 try {
Jack He8caab152018-03-02 13:08:36 -0800658 return Settings.Global.getInt(mContentResolver,
659 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700660 } catch (SettingNotFoundException e) {
661 }
662 return false;
663 }
664
Wei Wange4a744b2015-06-11 17:50:29 -0700665 // Monitor change of BLE scan only mode settings.
666 private void registerForBleScanModeChange() {
667 ContentObserver contentObserver = new ContentObserver(null) {
668 @Override
669 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800670 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800671 // Nothing to do
672 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800673 }
674 // BLE scan is not available.
675 disableBleScanMode();
676 clearBleApps();
677 try {
678 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800679 if (mBluetooth != null) {
680 mBluetooth.onBrEdrDown();
681 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800682 } catch (RemoteException e) {
683 Slog.e(TAG, "error when disabling bluetooth", e);
684 } finally {
685 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700686 }
687 }
688 };
689
690 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800691 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
692 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700693 }
694
695 // Disable ble scan only mode.
696 private void disableBleScanMode() {
697 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700698 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700699 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800700 if (DBG) {
701 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
702 }
Wei Wange4a744b2015-06-11 17:50:29 -0700703 mEnable = false;
704 }
705 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700706 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700707 } finally {
708 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700709 }
710 }
711
Marie Janssen59804562016-12-28 14:13:21 -0800712 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
713 ClientDeathRecipient r = mBleApps.get(token);
714 if (r == null && enable) {
715 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
716 try {
717 token.linkToDeath(deathRec, 0);
718 } catch (RemoteException ex) {
719 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800720 }
Marie Janssen59804562016-12-28 14:13:21 -0800721 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800722 if (DBG) {
723 Slog.d(TAG, "Registered for death of " + packageName);
724 }
Marie Janssen59804562016-12-28 14:13:21 -0800725 } else if (!enable && r != null) {
726 // Unregister death recipient as the app goes away.
727 token.unlinkToDeath(r, 0);
728 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800729 if (DBG) {
730 Slog.d(TAG, "Unregistered for death of " + packageName);
731 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800732 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800733 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800734 if (DBG) {
735 Slog.d(TAG, appCount + " registered Ble Apps");
736 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800737 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700738 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800740 if (appCount == 0 && !mEnableExternal) {
741 sendBrEdrDownCallback();
742 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800743 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800744 }
745
Wei Wange4a744b2015-06-11 17:50:29 -0700746 // Clear all apps using BLE scan only mode.
747 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800748 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700749 }
750
Marie Janssen59804562016-12-28 14:13:21 -0800751 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800752 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800753 if (DBG) {
754 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
755 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800756 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800757 }
758
759 /**
Marie Janssenfa630682016-12-15 13:51:30 -0800760 * Action taken when GattService is turned on
Nitin Arorad055adb2015-03-02 15:03:51 -0800761 */
762 private void onBluetoothGattServiceUp() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800763 if (DBG) {
764 Slog.d(TAG, "BluetoothGatt Service is Up");
765 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700766 try {
767 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800768 if (mBluetooth == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800769 if (DBG) {
770 Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!");
771 }
Marie Janssenfa630682016-12-15 13:51:30 -0800772 return;
773 }
774 int st = mBluetooth.getState();
775 if (st != BluetoothAdapter.STATE_BLE_ON) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800776 if (DBG) {
777 Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: "
778 + BluetoothAdapter.nameForState(st));
779 }
Marie Janssenfa630682016-12-15 13:51:30 -0800780 return;
781 }
782 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
783 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800784 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800785 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800786 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700787 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800788 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700789 } finally {
790 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800791 }
792 }
793
794 /**
795 * Inform BluetoothAdapter instances that BREDR part is down
796 * and turn off all service and stack if no LE app needs it
797 */
798 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800799 if (DBG) {
800 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
801 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700802
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700803 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700804 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700805 return;
806 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800807
Martin Brabhamc2b06222017-02-27 16:55:07 -0800808 if (isBleAppPresent()) {
809 // Need to stay at BLE ON. Disconnect all Gatt connections
810 try {
811 mBluetoothGatt.unregAll();
812 } catch (RemoteException e) {
813 Slog.e(TAG, "Unable to disconnect all apps.", e);
814 }
815 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800816 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700817 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800818 if (mBluetooth != null) {
819 mBluetooth.onBrEdrDown();
820 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700821 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700822 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700823 } finally {
824 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800825 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800826 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800827
Nitin Arorad055adb2015-03-02 15:03:51 -0800828 }
829
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800830 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100831 if (isBluetoothDisallowed()) {
832 if (DBG) {
833 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
834 }
835 return false;
836 }
837
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700838 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800839 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700840
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700841 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800842 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
843 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700844 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800845 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
846
847 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700848 throw new SecurityException("no permission to enable Bluetooth quietly");
849 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800850
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800851 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800852 mQuietEnableExternal = true;
853 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800854 sendEnableMsg(true,
855 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800856 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700857 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700858 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700859
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700860 public boolean enable(String packageName) throws RemoteException {
861 final int callingUid = Binder.getCallingUid();
862 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
863
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100864 if (isBluetoothDisallowed()) {
865 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800866 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100867 }
868 return false;
869 }
870
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700871 if (!callerSystem) {
872 if (!checkIfCallerIsForegroundUser()) {
873 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
874 return false;
875 }
876
877 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
878 "Need BLUETOOTH ADMIN permission");
879
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800880 if (!isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
881 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700882 return false;
883 }
fredcf2458862012-04-16 15:18:27 -0700884 }
885
Zhihai Xu401202b2012-12-03 11:36:21 -0800886 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800887 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
888 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700889 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800890
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800891 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800892 mQuietEnableExternal = false;
893 mEnableExternal = true;
894 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800895 sendEnableMsg(false,
896 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800897 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800898 if (DBG) {
899 Slog.d(TAG, "enable returning");
900 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800901 return true;
fredc0f420372012-04-12 00:02:00 -0700902 }
903
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700904 public boolean disable(String packageName, boolean persist) throws RemoteException {
905 final int callingUid = Binder.getCallingUid();
906 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700907
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700908 if (!callerSystem) {
909 if (!checkIfCallerIsForegroundUser()) {
910 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
911 return false;
912 }
913
914 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
915 "Need BLUETOOTH ADMIN permission");
916
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800917 if (isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
918 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700919 return false;
920 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700921 }
922
fredcf2458862012-04-16 15:18:27 -0700923 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800924 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700925 }
fredcf2458862012-04-16 15:18:27 -0700926
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800927 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800928 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800929 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800930 }
931 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800932 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
933 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800934 }
fredc0f420372012-04-12 00:02:00 -0700935 return true;
936 }
937
baishengf62d8692018-01-25 18:07:24 +0800938 private boolean startConsentUiIfNeeded(String packageName,
939 int callingUid, String intentAction) throws RemoteException {
940 if (checkBluetoothPermissionWhenPermissionReviewRequired()) {
941 return false;
942 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700943 try {
944 // Validate the package only if we are going to use it
945 ApplicationInfo applicationInfo = mContext.getPackageManager()
946 .getApplicationInfoAsUser(packageName,
947 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
948 UserHandle.getUserId(callingUid));
949 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800950 throw new SecurityException("Package " + packageName
951 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700952 }
953
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000954 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000955 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800956 intent.setFlags(
957 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000958 try {
959 mContext.startActivity(intent);
960 } catch (ActivityNotFoundException e) {
961 // Shouldn't happen
962 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
963 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700964 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000965 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700966 } catch (PackageManager.NameNotFoundException e) {
967 throw new RemoteException(e.getMessage());
968 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700969 }
970
baishengf62d8692018-01-25 18:07:24 +0800971 /**
972 * Check if the caller must still pass permission check or if the caller is exempted
973 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED check.
974 *
975 * Commands from some callers may be exempted from triggering the consent UI when
976 * enabling bluetooth. This exemption is checked via the
977 * MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED and allows calls to skip
978 * the consent UI where it may otherwise be required.
979 *
980 * @hide
981 */
982 private boolean checkBluetoothPermissionWhenPermissionReviewRequired() {
983 if (!mPermissionReviewRequired) {
984 return false;
985 }
986 int result = mContext.checkCallingPermission(
987 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED);
988 return result == PackageManager.PERMISSION_GRANTED;
989 }
990
fredc649fe492012-04-19 01:07:18 -0700991 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700992 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800993 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
994 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -0700995 }
996
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700997 try {
998 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800999 if (mUnbinding) {
1000 return;
1001 }
fredc0f420372012-04-12 00:02:00 -07001002 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001003 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001004 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001005 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001006 //Unregister callback object
1007 try {
1008 mBluetooth.unregisterCallback(mBluetoothCallback);
1009 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001010 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001011 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001012 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001013 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001014 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001015 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001016 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001017 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001018 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001019 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001020 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001021 } finally {
1022 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001023 }
1024 }
1025
Matthew Xieddf7e472013-03-01 18:41:02 -08001026 public IBluetoothGatt getBluetoothGatt() {
1027 // sync protection
1028 return mBluetoothGatt;
1029 }
1030
Benjamin Franze8b98922014-11-12 15:57:54 +00001031 @Override
1032 public boolean bindBluetoothProfileService(int bluetoothProfile,
1033 IBluetoothProfileServiceConnection proxy) {
1034 if (!mEnable) {
1035 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001036 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1037 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001038 }
1039 return false;
1040 }
1041 synchronized (mProfileServices) {
1042 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1043 if (psc == null) {
1044 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001045 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1046 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001047 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001048
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001049 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1050 return false;
1051 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001052
1053 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001054 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001055 if (!psc.bindService()) {
1056 return false;
1057 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001058
Benjamin Franze8b98922014-11-12 15:57:54 +00001059 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001060 }
1061 }
1062
1063 // Introducing a delay to give the client app time to prepare
1064 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1065 addProxyMsg.arg1 = bluetoothProfile;
1066 addProxyMsg.obj = proxy;
1067 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1068 return true;
1069 }
1070
1071 @Override
1072 public void unbindBluetoothProfileService(int bluetoothProfile,
1073 IBluetoothProfileServiceConnection proxy) {
1074 synchronized (mProfileServices) {
1075 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1076 if (psc == null) {
1077 return;
1078 }
1079 psc.removeProxy(proxy);
1080 }
1081 }
1082
1083 private void unbindAllBluetoothProfileServices() {
1084 synchronized (mProfileServices) {
1085 for (Integer i : mProfileServices.keySet()) {
1086 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001087 try {
1088 mContext.unbindService(psc);
1089 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001090 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001091 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001092 psc.removeAllProxies();
1093 }
1094 mProfileServices.clear();
1095 }
1096 }
1097
1098 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001099 * Send enable message and set adapter name and address. Called when the boot phase becomes
1100 * PHASE_SYSTEM_SERVICES_READY.
1101 */
1102 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001103 if (DBG) {
1104 Slog.d(TAG, "Bluetooth boot completed");
1105 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001106 UserManagerInternal userManagerInternal =
1107 LocalServices.getService(UserManagerInternal.class);
1108 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001109 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001110 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001111 return;
1112 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001113 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001114 if (DBG) {
1115 Slog.d(TAG, "Auto-enabling Bluetooth.");
1116 }
Jack He8caab152018-03-02 13:08:36 -08001117 sendEnableMsg(mQuietEnableExternal,
1118 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1119 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001120 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001121 if (DBG) {
1122 Slog.d(TAG, "Getting adapter name and address");
1123 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001124 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1125 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001126 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001127 }
1128
1129 /**
1130 * Called when switching to a different foreground user.
1131 */
1132 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001133 if (DBG) {
1134 Slog.d(TAG, "User " + userHandle + " switched");
1135 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001136 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1137 }
1138
1139 /**
1140 * Called when user is unlocked.
1141 */
1142 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001143 if (DBG) {
1144 Slog.d(TAG, "User " + userHandle + " unlocked");
1145 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001146 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001147 }
1148
1149 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001150 * This class manages the clients connected to a given ProfileService
1151 * and maintains the connection with that service.
1152 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001153 private final class ProfileServiceConnections
1154 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001155 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001156 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001157 IBinder mService;
1158 ComponentName mClassName;
1159 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001160 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001161
1162 ProfileServiceConnections(Intent intent) {
1163 mService = null;
1164 mClassName = null;
1165 mIntent = intent;
1166 }
1167
Benjamin Franz5b614592014-12-09 18:58:45 +00001168 private boolean bindService() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001169 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1170 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001171 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1172 msg.obj = this;
1173 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001174 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001175 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001176 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001177 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001178 }
1179
1180 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1181 mProxies.register(proxy);
1182 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001183 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001184 proxy.onServiceConnected(mClassName, mService);
1185 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001186 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001187 }
1188 } else {
1189 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1190 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1191 msg.obj = this;
1192 mHandler.sendMessage(msg);
1193 }
1194 }
1195 }
1196
1197 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1198 if (proxy != null) {
1199 if (mProxies.unregister(proxy)) {
1200 try {
1201 proxy.onServiceDisconnected(mClassName);
1202 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001203 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001204 }
1205 }
1206 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001207 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001208 }
1209 }
1210
1211 private void removeAllProxies() {
1212 onServiceDisconnected(mClassName);
1213 mProxies.kill();
1214 }
1215
1216 @Override
1217 public void onServiceConnected(ComponentName className, IBinder service) {
1218 // remove timeout message
1219 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1220 mService = service;
1221 mClassName = className;
1222 try {
1223 mService.linkToDeath(this, 0);
1224 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001225 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001226 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001227
1228 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001229 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001230 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001231 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001232 mInvokingProxyCallbacks = true;
1233
1234 final int n = mProxies.beginBroadcast();
1235 try {
1236 for (int i = 0; i < n; i++) {
1237 try {
1238 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1239 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001240 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001241 }
1242 }
1243 } finally {
1244 mProxies.finishBroadcast();
1245 mInvokingProxyCallbacks = false;
1246 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001247 }
1248
1249 @Override
1250 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001251 if (mService == null) {
1252 return;
1253 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001254 mService.unlinkToDeath(this, 0);
1255 mService = null;
1256 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001257
1258 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001259 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001260 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001261 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001262 mInvokingProxyCallbacks = true;
1263
1264 final int n = mProxies.beginBroadcast();
1265 try {
1266 for (int i = 0; i < n; i++) {
1267 try {
1268 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1269 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001270 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001271 }
1272 }
1273 } finally {
1274 mProxies.finishBroadcast();
1275 mInvokingProxyCallbacks = false;
1276 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001277 }
1278
1279 @Override
1280 public void binderDied() {
1281 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001282 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001283 }
1284 onServiceDisconnected(mClassName);
1285 // Trigger rebind
1286 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1287 msg.obj = this;
1288 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1289 }
1290 }
1291
fredcbf072a72012-05-09 16:52:50 -07001292 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001293 try {
1294 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001295 if (DBG) {
1296 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1297 + " receivers.");
1298 }
1299 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001300 try {
1301 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1302 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001303 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001304 }
fredcbf072a72012-05-09 16:52:50 -07001305 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001306 } finally {
1307 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001308 }
fredcbf072a72012-05-09 16:52:50 -07001309 }
1310
1311 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001312 * Inform BluetoothAdapter instances that Adapter service is up
1313 */
1314 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001315 try {
1316 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001317 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1318 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001319 try {
1320 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001321 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001322 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001323 }
1324 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001325 } finally {
1326 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001327 }
1328 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001329
Zhihai Xu40874a02012-10-08 17:57:03 -07001330 /**
fredcbf072a72012-05-09 16:52:50 -07001331 * Inform BluetoothAdapter instances that Adapter service is down
1332 */
1333 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001334 try {
1335 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001336 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1337 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001338 try {
1339 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001340 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001341 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001342 }
1343 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001344 } finally {
1345 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001346 }
1347 }
Svet Ganov408abf72015-05-12 19:13:36 -07001348
fredc0f420372012-04-12 00:02:00 -07001349 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001350 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001351
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001352 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1353 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001354 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001355 }
1356
Svet Ganov408abf72015-05-12 19:13:36 -07001357 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1358 != PackageManager.PERMISSION_GRANTED) {
1359 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1360 }
1361
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001362 try {
1363 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001364 if (mBluetooth != null) {
1365 return mBluetooth.getAddress();
1366 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001367 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001368 Slog.e(TAG,
1369 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1370 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001371 } finally {
1372 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001373 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001374
Matthew Xiecdce0b92012-07-12 19:06:15 -07001375 // mAddress is accessed from outside.
1376 // It is alright without a lock. Here, bluetooth is off, no other thread is
1377 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001378 return mAddress;
1379 }
fredc649fe492012-04-19 01:07:18 -07001380
fredc0f420372012-04-12 00:02:00 -07001381 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001382 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001383
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001384 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1385 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001386 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001387 }
1388
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001389 try {
1390 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001391 if (mBluetooth != null) {
1392 return mBluetooth.getName();
1393 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001394 } catch (RemoteException e) {
1395 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1396 } finally {
1397 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001398 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001399
Matthew Xiecdce0b92012-07-12 19:06:15 -07001400 // mName is accessed from outside.
1401 // It alright without a lock. Here, bluetooth is off, no other thread is
1402 // changing mName
fredc0f420372012-04-12 00:02:00 -07001403 return mName;
1404 }
1405
fredc0f420372012-04-12 00:02:00 -07001406 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001407 public void onServiceConnected(ComponentName componentName, IBinder service) {
1408 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001409 if (DBG) {
1410 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1411 }
fredc0f420372012-04-12 00:02:00 -07001412 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001413 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001414 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001415 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001416 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1417 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001418 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001419 return;
1420 }
fredc0f420372012-04-12 00:02:00 -07001421 msg.obj = service;
1422 mHandler.sendMessage(msg);
1423 }
1424
Marie Janssencb21ad72016-12-13 10:51:02 -08001425 public void onServiceDisconnected(ComponentName componentName) {
1426 // Called if we unexpectedly disconnect.
1427 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001428 if (DBG) {
1429 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1430 }
fredc0f420372012-04-12 00:02:00 -07001431 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001432 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001433 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001434 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001435 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1436 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001437 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001438 return;
1439 }
fredc0f420372012-04-12 00:02:00 -07001440 mHandler.sendMessage(msg);
1441 }
1442 }
1443
1444 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1445
Zhihai Xu40874a02012-10-08 17:57:03 -07001446 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001447 boolean mGetNameAddressOnly = false;
1448
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001449 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001450 super(looper);
1451 }
1452
fredc0f420372012-04-12 00:02:00 -07001453 @Override
1454 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001455 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001456 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001457 if (DBG) {
1458 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1459 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001460 try {
1461 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001462 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001463 if (DBG) {
1464 Slog.d(TAG, "Binding to service to get name and address");
1465 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001466 mGetNameAddressOnly = true;
1467 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1468 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1469 Intent i = new Intent(IBluetooth.class.getName());
1470 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001471 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1472 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001473 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1474 } else {
1475 mBinding = true;
1476 }
1477 } else if (mBluetooth != null) {
1478 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001479 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001480 } catch (RemoteException re) {
1481 Slog.e(TAG, "Unable to grab names", re);
1482 }
1483 if (mGetNameAddressOnly && !mEnable) {
1484 unbindAndFinish();
1485 }
1486 mGetNameAddressOnly = false;
1487 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001488 } finally {
1489 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001490 }
1491 break;
1492
Matthew Xiecdce0b92012-07-12 19:06:15 -07001493 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001494 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001495 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001496 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001497 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1498 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001499
1500 // Use service interface to get the exact state
1501 try {
1502 mBluetoothLock.readLock().lock();
1503 if (mBluetooth != null) {
1504 int state = mBluetooth.getState();
1505 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001506 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001507 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001508 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001509 break;
1510 }
1511 }
1512 } catch (RemoteException e) {
1513 Slog.e(TAG, "", e);
1514 } finally {
1515 mBluetoothLock.readLock().unlock();
1516 }
1517
1518 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001519 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001520 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001521 } else {
1522 //
1523 // We need to wait until transitioned to STATE_OFF and
1524 // the previous Bluetooth process has exited. The
1525 // waiting period has three components:
1526 // (a) Wait until the local state is STATE_OFF. This
1527 // is accomplished by "waitForOnOff(false, true)".
1528 // (b) Wait until the STATE_OFF state is updated to
1529 // all components.
1530 // (c) Wait until the Bluetooth process exits, and
1531 // ActivityManager detects it.
1532 // The waiting for (b) and (c) is accomplished by
1533 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1534 // message. On slower devices, that delay needs to be
1535 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1536 //
1537 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001538 Message restartMsg =
1539 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1540 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001541 }
fredc649fe492012-04-19 01:07:18 -07001542 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001543
fredc0f420372012-04-12 00:02:00 -07001544 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001545 if (DBG) {
1546 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1547 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001548 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1549 if (mEnable && mBluetooth != null) {
1550 waitForOnOff(true, false);
1551 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001552 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001553 waitForOnOff(false, false);
1554 } else {
1555 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001556 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001557 }
fredc0f420372012-04-12 00:02:00 -07001558 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001559
Stanley Tng873b5702017-05-01 21:27:31 -07001560 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001561 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1562 if (DBG) {
1563 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001564 }
Jack He8caab152018-03-02 13:08:36 -08001565 persistBluetoothSetting(BLUETOOTH_OFF);
1566 mEnableExternal = false;
1567 sendDisableMsg(
1568 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1569 mContext.getPackageName());
1570 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1571 if (DBG) {
1572 Slog.d(TAG, "Restore Bluetooth state to enabled");
1573 }
1574 mQuietEnableExternal = false;
1575 mEnableExternal = true;
1576 // waive WRITE_SECURE_SETTINGS permission check
1577 sendEnableMsg(false,
1578 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1579 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001580 }
1581 break;
1582
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001583 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001584 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001585 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001586 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001587 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001588 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001589 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001590 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001591 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001592 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001593 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1594 IBluetoothStateChangeCallback callback =
1595 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001596 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001597 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001598 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001599 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1600 IBluetoothStateChangeCallback callback =
1601 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001602 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001603 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001604 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001605 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001606 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001607 if (psc == null) {
1608 break;
1609 }
1610 IBluetoothProfileServiceConnection proxy =
1611 (IBluetoothProfileServiceConnection) msg.obj;
1612 psc.addProxy(proxy);
1613 break;
1614 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001615 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001616 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1617 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1618 if (psc == null) {
1619 break;
1620 }
1621 psc.bindService();
1622 break;
1623 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001624 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1625 if (DBG) {
1626 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1627 }
fredc0f420372012-04-12 00:02:00 -07001628
1629 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001630 try {
1631 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001632 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001633 mBluetoothGatt =
1634 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Nitin Arorad055adb2015-03-02 15:03:51 -08001635 onBluetoothGattServiceUp();
Matthew Xieddf7e472013-03-01 18:41:02 -08001636 break;
1637 } // else must be SERVICE_IBLUETOOTH
1638
1639 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001640 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001641
fredc0f420372012-04-12 00:02:00 -07001642 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001643 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001644 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001645
Ajay Panicker4bb48302016-03-31 14:14:27 -07001646 if (!isNameAndAddressSet()) {
1647 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1648 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001649 if (mGetNameAddressOnly) {
1650 return;
1651 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001652 }
1653
Matthew Xiecdce0b92012-07-12 19:06:15 -07001654 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001655 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001656 mBluetooth.registerCallback(mBluetoothCallback);
1657 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001658 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001659 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001660 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001661 sendBluetoothServiceUpCallback();
1662
Matthew Xiecdce0b92012-07-12 19:06:15 -07001663 //Do enable request
1664 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001665 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001666 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001667 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001668 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001669 } else {
1670 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001671 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001672 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001673 }
1674 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001675 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001676 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001677 } finally {
1678 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001679 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001680
1681 if (!mEnable) {
1682 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001683 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001684 waitForOnOff(false, false);
1685 }
fredc649fe492012-04-19 01:07:18 -07001686 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001687 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001688 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001689 int prevState = msg.arg1;
1690 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001691 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001692 Slog.d(TAG,
1693 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1694 prevState) + " > " + BluetoothAdapter.nameForState(
1695 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001696 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001697 mState = newState;
1698 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001699 // handle error state transition case from TURNING_ON to OFF
1700 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001701 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1702 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001703 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001704 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001705 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1706 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001707 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001708 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001709 // If we tried to enable BT while BT was in the process of shutting down,
1710 // wait for the BT process to fully tear down and then force a restart
1711 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001712 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1713 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001714 if (mEnable) {
1715 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1716 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001717 Message restartMsg =
1718 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001719 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1720 }
1721 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001722 if (newState == BluetoothAdapter.STATE_ON
1723 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001724 // bluetooth is working, reset the counter
1725 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001726 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001727 mErrorRecoveryRetryCounter = 0;
1728 }
1729 }
fredc649fe492012-04-19 01:07:18 -07001730 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001731 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001732 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001733 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001734 try {
1735 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001736 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1737 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001738 if (mBluetooth == null) {
1739 break;
1740 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001741 mBluetooth = null;
1742 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1743 mBluetoothGatt = null;
1744 break;
1745 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001746 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001747 break;
1748 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001749 } finally {
1750 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301751 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001752
Marie Janssene54b4222017-03-16 18:10:59 -07001753 // log the unexpected crash
1754 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001755 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1756 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001757 if (mEnable) {
1758 mEnable = false;
1759 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001760 Message restartMsg =
1761 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1762 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001763 }
1764
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001765 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001766
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001767 // Send BT state broadcast to update
1768 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001769 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1770 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001771 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001772 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001773 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001774 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001775 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1776 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001777 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001778 }
1779
1780 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1781 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001782 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001783 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001784 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001785 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301786 /* Enable without persisting the setting as
1787 it doesnt change when IBluetooth
1788 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001789 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001790 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1791 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001792 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301793 break;
1794 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001795 case MESSAGE_TIMEOUT_BIND: {
1796 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1797 mBluetoothLock.writeLock().lock();
1798 mBinding = false;
1799 mBluetoothLock.writeLock().unlock();
1800 break;
1801 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001802 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001803 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001804 mBluetoothLock.writeLock().lock();
1805 mUnbinding = false;
1806 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001807 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001808 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001809
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001810 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001811 if (DBG) {
1812 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1813 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001814 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001815
Zhihai Xu40874a02012-10-08 17:57:03 -07001816 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001817 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001818 try {
1819 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001820 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001821 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001822 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001823 } catch (RemoteException re) {
1824 Slog.e(TAG, "Unable to unregister", re);
1825 } finally {
1826 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001827 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001828
1829 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1830 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1831 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1832 mState = BluetoothAdapter.STATE_OFF;
1833 }
1834 if (mState == BluetoothAdapter.STATE_OFF) {
1835 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1836 mState = BluetoothAdapter.STATE_TURNING_ON;
1837 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001838
1839 waitForOnOff(true, false);
1840
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001841 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1842 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1843 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001844
Benjamin Franze8b98922014-11-12 15:57:54 +00001845 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001846 // disable
Jack He8caab152018-03-02 13:08:36 -08001847 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1848 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001849 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001850 // Pbap service need receive STATE_TURNING_OFF intent to close
1851 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001852 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001853
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001854 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001855
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001856 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001857 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001858 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001859
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001860 try {
1861 mBluetoothLock.writeLock().lock();
1862 if (mBluetooth != null) {
1863 mBluetooth = null;
1864 // Unbind
1865 mContext.unbindService(mConnection);
1866 }
1867 mBluetoothGatt = null;
1868 } finally {
1869 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001870 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001871
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001872 //
1873 // If disabling Bluetooth times out, wait for an
1874 // additional amount of time to ensure the process is
1875 // shut down completely before attempting to restart.
1876 //
1877 if (didDisableTimeout) {
1878 SystemClock.sleep(3000);
1879 } else {
1880 SystemClock.sleep(100);
1881 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001882
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001883 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1884 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001885 // enable
Jack He8caab152018-03-02 13:08:36 -08001886 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1887 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001888 // mEnable flag could have been reset on disableBLE. Reenable it.
1889 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001890 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001891 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001892 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1893 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001894 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001895 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1896 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001897 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001898 }
John Spurlock8a985d22014-02-25 09:40:05 -05001899 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001900 break;
1901 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001902 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001903 if (DBG) {
1904 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1905 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001906 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1907
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001908 if (mEnable && !mBinding && (mBluetooth == null)) {
1909 // We should be connected, but we gave up for some
1910 // reason; maybe the Bluetooth service wasn't encryption
1911 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001912 if (DBG) {
1913 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1914 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001915 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001916 }
1917 }
fredc0f420372012-04-12 00:02:00 -07001918 }
1919 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001920 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001921
Zhihai Xu401202b2012-12-03 11:36:21 -08001922 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001923 mQuietEnable = quietMode;
1924
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001925 try {
1926 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001927 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001928 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001929 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1930 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001931 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001932 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001933 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001934 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001935 } else {
1936 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001937 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001938 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001939 //Enable bluetooth
1940 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001941 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001942 if (!mBluetooth.enable()) {
1943 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001944 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001945 } else {
1946 if (!mBluetooth.enableNoAutoConnect()) {
1947 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001948 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001949 }
1950 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001951 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001952 }
1953 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001954 } finally {
1955 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001956 }
1957 }
1958
Dianne Hackborn221ea892013-08-04 16:50:16 -07001959 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1960 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1961 intent.setComponent(comp);
1962 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001963 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001964 return false;
1965 }
1966 return true;
1967 }
1968
Zhihai Xu401202b2012-12-03 11:36:21 -08001969 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001970 try {
1971 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001972 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001973 if (DBG) {
1974 Slog.d(TAG, "Sending off request.");
1975 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001976 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001977 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001978 }
1979 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001980 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001981 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001982 } finally {
1983 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001984 }
1985 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001986
1987 private boolean checkIfCallerIsForegroundUser() {
1988 int foregroundUser;
1989 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001990 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07001991 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00001992 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1993 UserInfo ui = um.getProfileParent(callingUser);
1994 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001995 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07001996 boolean valid = false;
1997 try {
1998 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001999 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2000 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002001 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002002 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2003 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2004 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002005 }
2006 } finally {
2007 Binder.restoreCallingIdentity(callingIdentity);
2008 }
2009 return valid;
2010 }
2011
Nitin Arorad055adb2015-03-02 15:03:51 -08002012 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002013 if (DBG) {
2014 Slog.d(TAG,
2015 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2016 + BluetoothAdapter.nameForState(newState));
2017 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002018 // Send broadcast message to everyone else
2019 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2020 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2021 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2022 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2023 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2024 }
2025
Zhihai Xu40874a02012-10-08 17:57:03 -07002026 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002027 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002028 if (prevState == newState) { // No change. Nothing to do.
2029 return;
2030 }
2031 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002032 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002033 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002034 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002035
Marie Janssencb21ad72016-12-13 10:51:02 -08002036 if (newState == BluetoothAdapter.STATE_OFF) {
2037 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002038 if (DBG) {
2039 Slog.d(TAG, "Bluetooth is complete send Service Down");
2040 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002041 sendBluetoothServiceDownCallback();
2042 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002043 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002044 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002045 isStandardBroadcast = false;
2046
Marie Janssencb21ad72016-12-13 10:51:02 -08002047 } else if (!intermediate_off) {
2048 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002049 if (DBG) {
2050 Slog.d(TAG, "Bluetooth is in LE only mode");
2051 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002052 if (mBluetoothGatt != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002053 if (DBG) {
2054 Slog.d(TAG, "Calling BluetoothGattServiceUp");
2055 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002056 onBluetoothGattServiceUp();
2057 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002058 if (DBG) {
2059 Slog.d(TAG, "Binding Bluetooth GATT service");
2060 }
2061 if (mContext.getPackageManager()
2062 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002063 Intent i = new Intent(IBluetoothGatt.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002064 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2065 UserHandle.CURRENT);
Marie Janssencb21ad72016-12-13 10:51:02 -08002066 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002067 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002068 sendBleStateChanged(prevState, newState);
2069 //Don't broadcase this as std intent
2070 isStandardBroadcast = false;
2071
2072 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002073 if (DBG) {
2074 Slog.d(TAG, "Intermediate off, back to LE only mode");
2075 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002076 // For LE only mode, broadcast as is
2077 sendBleStateChanged(prevState, newState);
2078 sendBluetoothStateCallback(false); // BT is OFF for general users
2079 // Broadcast as STATE_OFF
2080 newState = BluetoothAdapter.STATE_OFF;
2081 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002082 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002083 } else if (newState == BluetoothAdapter.STATE_ON) {
2084 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2085 sendBluetoothStateCallback(isUp);
2086 sendBleStateChanged(prevState, newState);
2087
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002088 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2089 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002090 sendBleStateChanged(prevState, newState);
2091 isStandardBroadcast = false;
2092
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002093 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2094 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002095 sendBleStateChanged(prevState, newState);
2096 }
2097
2098 if (isStandardBroadcast) {
2099 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2100 // Show prevState of BLE_ON as OFF to standard users
2101 prevState = BluetoothAdapter.STATE_OFF;
2102 }
2103 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2104 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2105 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2106 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2107 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002108 }
2109 }
2110
2111 /**
2112 * if on is true, wait for state become ON
2113 * if off is true, wait for state become OFF
2114 * if both on and off are false, wait for state not ON
2115 */
2116 private boolean waitForOnOff(boolean on, boolean off) {
2117 int i = 0;
2118 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002119 try {
2120 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002121 if (mBluetooth == null) {
2122 break;
2123 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002124 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002125 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2126 return true;
2127 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002128 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002129 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2130 return true;
2131 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002132 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002133 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2134 return true;
2135 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002136 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002137 } catch (RemoteException e) {
2138 Slog.e(TAG, "getState()", e);
2139 break;
2140 } finally {
2141 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002142 }
2143 if (on || off) {
2144 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002145 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002146 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002147 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002148 i++;
2149 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002150 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002151 return false;
2152 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002153
Jack He8caab152018-03-02 13:08:36 -08002154 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002155 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002156 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002157 }
2158
Jack He8caab152018-03-02 13:08:36 -08002159 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002160 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002161 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002162 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002163 }
2164
Jack He8caab152018-03-02 13:08:36 -08002165 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002166 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002167 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002168 mActiveLogs.remove();
2169 }
Jack He8caab152018-03-02 13:08:36 -08002170 mActiveLogs.add(
2171 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002172 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002173
2174 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2175 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2176 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2177 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002178 }
2179
Marie Janssene54b4222017-03-16 18:10:59 -07002180 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002181 synchronized (mCrashTimestamps) {
2182 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2183 mCrashTimestamps.removeFirst();
2184 }
2185 mCrashTimestamps.add(System.currentTimeMillis());
2186 mCrashes++;
2187 }
Marie Janssene54b4222017-03-16 18:10:59 -07002188 }
2189
Marie Janssen2977c3e2016-11-09 12:01:24 -08002190 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002191 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002192 try {
2193 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002194 if (mBluetooth != null) {
2195 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002196 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002197 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002198 } catch (RemoteException re) {
2199 Slog.e(TAG, "Unable to unregister", re);
2200 } finally {
2201 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002202 }
2203
2204 SystemClock.sleep(500);
2205
2206 // disable
Jack He8caab152018-03-02 13:08:36 -08002207 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2208 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002209 handleDisable();
2210
2211 waitForOnOff(false, true);
2212
2213 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002214
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002215 try {
2216 mBluetoothLock.writeLock().lock();
2217 if (mBluetooth != null) {
2218 mBluetooth = null;
2219 // Unbind
2220 mContext.unbindService(mConnection);
2221 }
2222 mBluetoothGatt = null;
2223 } finally {
2224 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002225 }
2226
2227 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2228 mState = BluetoothAdapter.STATE_OFF;
2229
Marie Janssen2977c3e2016-11-09 12:01:24 -08002230 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002231 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002232 }
2233
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002234 mEnable = false;
2235
2236 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2237 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002238 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002239 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2240 } else {
2241 // todo: notify user to power down and power up phone to make bluetooth work.
2242 }
2243 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002244
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002245 private boolean isBluetoothDisallowed() {
2246 long callingIdentity = Binder.clearCallingIdentity();
2247 try {
2248 return mContext.getSystemService(UserManager.class)
2249 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2250 } finally {
2251 Binder.restoreCallingIdentity(callingIdentity);
2252 }
2253 }
2254
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002255 /**
2256 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002257 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2258 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002259 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002260 * @param userId user to disable bluetooth sharing for.
2261 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002262 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002263 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002264 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2265 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002266 final int newState =
2267 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2268 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002269 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002270 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002271 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2272 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002273 } catch (Exception e) {
2274 // The component was not found, do nothing.
2275 }
2276 }
2277
Mike Lockwood726d4de2014-10-28 14:06:28 -07002278 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002279 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002280 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2281 return;
2282 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002283 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002284
2285 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2286
2287 if (!protoOut) {
2288 writer.println("Bluetooth Status");
2289 writer.println(" enabled: " + isEnabled());
2290 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2291 writer.println(" address: " + mAddress);
2292 writer.println(" name: " + mName);
2293 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002294 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002295 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2296 (int) (onDuration / (1000 * 60 * 60)),
2297 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2298 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002299 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002300 }
2301
Marie Janssena95924d2017-01-18 09:37:52 -08002302 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002303 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002304 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002305 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002306 for (ActiveLog log : mActiveLogs) {
2307 writer.println(" " + log);
2308 }
Marie Janssen59804562016-12-28 14:13:21 -08002309 }
2310
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002311 writer.println(
2312 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2313 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2314 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2315 }
Marie Janssene54b4222017-03-16 18:10:59 -07002316 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002317 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002318 }
2319
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002320 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2321 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002322 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002323 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002324 }
2325
Marie Janssena95924d2017-01-18 09:37:52 -08002326 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002327 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002328 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002329 // Add arg to produce output
2330 args = new String[1];
2331 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002332 }
Marie Janssen59804562016-12-28 14:13:21 -08002333 }
2334
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002335 if (mBluetoothBinder == null) {
2336 errorMsg = "Bluetooth Service not connected";
2337 } else {
2338 try {
2339 mBluetoothBinder.dump(fd, args);
2340 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002341 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002342 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002343 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002344 if (errorMsg != null) {
2345 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002346 if (protoOut) {
2347 return;
2348 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002349 writer.println(errorMsg);
2350 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002351 }
Jack He8caab152018-03-02 13:08:36 -08002352
2353 private static String getEnableDisableReasonString(int reason) {
2354 switch (reason) {
2355 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2356 return "APPLICATION_REQUEST";
2357 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2358 return "AIRPLANE_MODE";
2359 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2360 return "DISALLOWED";
2361 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2362 return "RESTARTED";
2363 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2364 return "START_ERROR";
2365 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2366 return "SYSTEM_BOOT";
2367 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2368 return "CRASH";
2369 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2370 return "USER_SWITCH";
2371 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2372 return "RESTORE_USER_SETTING";
2373 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2374 default: return "UNKNOWN[" + reason + "]";
2375 }
2376 }
fredc0f420372012-04-12 00:02:00 -07002377}