blob: 5ea3390d4e46f661cd636e607993e7d6e1b4d7a1 [file] [log] [blame]
fredc0f420372012-04-12 00:02:00 -07001/*
Zhihai Xufa0fd392012-10-23 17:31:56 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
fredc0f420372012-04-12 00:02:00 -070015 */
16
17package com.android.server;
18
Svet Ganov408abf72015-05-12 19:13:36 -070019import android.Manifest;
Zhihai Xu40874a02012-10-08 17:57:03 -070020import android.app.ActivityManager;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010021import android.app.AppGlobals;
fredc0f420372012-04-12 00:02:00 -070022import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000023import android.bluetooth.BluetoothProfile;
Jack He8caab152018-03-02 13:08:36 -080024import android.bluetooth.BluetoothProtoEnums;
fredc0f420372012-04-12 00:02:00 -070025import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070026import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070027import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000028import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070029import android.bluetooth.IBluetoothManager;
30import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000031import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070032import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070033import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070034import android.content.BroadcastReceiver;
35import android.content.ComponentName;
36import android.content.ContentResolver;
37import android.content.Context;
38import android.content.Intent;
39import android.content.IntentFilter;
40import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070041import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010042import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070043import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000044import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070045import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070046import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010047import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070048import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070049import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070050import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070051import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070052import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070053import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070054import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070055import android.os.SystemClock;
Stanley Tngcbfcbd12018-06-19 08:48:10 -070056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000058import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010059import android.os.UserManagerInternal;
60import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070061import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070062import android.provider.Settings.SettingNotFoundException;
Stanley Tngcbfcbd12018-06-19 08:48:10 -070063import android.text.TextUtils;
64import android.util.FeatureFlagUtils;
65import android.util.Log;
Jeff Sharkey67609c72016-03-05 14:29:13 -070066import android.util.Slog;
Tej Singhd8e7cc62018-03-22 18:30:31 +000067import android.util.StatsLog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070068
Arthur Hsuf3f95a92018-01-11 16:46:22 -080069import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060070import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010071import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010072
Mike Lockwood726d4de2014-10-28 14:06:28 -070073import java.io.FileDescriptor;
74import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000075import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080076import java.util.LinkedList;
Myles Watsonb5cd11a2017-11-27 16:42:11 -080077import java.util.Locale;
Benjamin Franze8b98922014-11-12 15:57:54 +000078import java.util.Map;
Chienyuan177156b2018-12-18 10:40:25 +080079import java.util.NoSuchElementException;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010080import java.util.concurrent.ConcurrentHashMap;
81import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070082
Marie Janssen59804562016-12-28 14:13:21 -080083
fredc0f420372012-04-12 00:02:00 -070084class BluetoothManagerService extends IBluetoothManager.Stub {
85 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070086 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070087
fredc0f420372012-04-12 00:02:00 -070088 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
89 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070090
Myles Watsonb5cd11a2017-11-27 16:42:11 -080091 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
92 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";
93 private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070094
95 private static final int ACTIVE_LOG_MAX_SIZE = 20;
96 private static final int CRASH_LOG_MAX_SIZE = 100;
Marie Janssene54b4222017-03-16 18:10:59 -070097
fredc0f420372012-04-12 00:02:00 -070098 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053099 //Maximum msec to wait for service restart
100 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800101 //Maximum msec to wait for restart due to error
102 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700103 //Maximum msec to delay MESSAGE_USER_SWITCHED
104 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000105 // Delay for the addProxy function in msec
106 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700107
108 private static final int MESSAGE_ENABLE = 1;
109 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700110 private static final int MESSAGE_REGISTER_ADAPTER = 20;
111 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
112 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
113 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
114 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
115 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530116 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700117 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
118 private static final int MESSAGE_TIMEOUT_BIND = 100;
119 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700120 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700121 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700122 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000123 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
124 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Stanley Tng873b5702017-05-01 21:27:31 -0700125 private static final int MESSAGE_RESTORE_USER_SETTING = 500;
126
127 private static final int RESTORE_SETTING_TO_ON = 1;
128 private static final int RESTORE_SETTING_TO_OFF = 0;
Marie Janssencb21ad72016-12-13 10:51:02 -0800129
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700130 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800131
Zhihai Xu401202b2012-12-03 11:36:21 -0800132 // Bluetooth persisted setting is off
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800133 private static final int BLUETOOTH_OFF = 0;
Zhihai Xu401202b2012-12-03 11:36:21 -0800134 // Bluetooth persisted setting is on
135 // and Airplane mode won't affect Bluetooth state at start up
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800136 private static final int BLUETOOTH_ON_BLUETOOTH = 1;
Zhihai Xu401202b2012-12-03 11:36:21 -0800137 // Bluetooth persisted setting is on
138 // but Airplane mode will affect Bluetooth state at start up
139 // and Airplane mode will have higher priority.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800140 private static final int BLUETOOTH_ON_AIRPLANE = 2;
fredc0f420372012-04-12 00:02:00 -0700141
Matthew Xieddf7e472013-03-01 18:41:02 -0800142 private static final int SERVICE_IBLUETOOTH = 1;
143 private static final int SERVICE_IBLUETOOTHGATT = 2;
144
fredc0f420372012-04-12 00:02:00 -0700145 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700146
147 // Locks are not provided for mName and mAddress.
148 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700149 private String mAddress;
150 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700151 private final ContentResolver mContentResolver;
152 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
153 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800154 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700155 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800156 private IBluetoothGatt mBluetoothGatt;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800157 private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700158 private boolean mBinding;
159 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800160
Zhihai Xu401202b2012-12-03 11:36:21 -0800161 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700162 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800163 private boolean mEnable;
164
Jack He8caab152018-03-02 13:08:36 -0800165 private static CharSequence timeToLog(long timestamp) {
Marie Janssene54b4222017-03-16 18:10:59 -0700166 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
167 }
168
Marie Janssen59804562016-12-28 14:13:21 -0800169 /**
170 * Used for tracking apps that enabled / disabled Bluetooth.
171 */
172 private class ActiveLog {
Jack He8caab152018-03-02 13:08:36 -0800173 private int mReason;
Marie Janssen59804562016-12-28 14:13:21 -0800174 private String mPackageName;
175 private boolean mEnable;
176 private long mTimestamp;
177
Jack He8caab152018-03-02 13:08:36 -0800178 ActiveLog(int reason, String packageName, boolean enable, long timestamp) {
179 mReason = reason;
Marie Janssen59804562016-12-28 14:13:21 -0800180 mPackageName = packageName;
181 mEnable = enable;
182 mTimestamp = timestamp;
183 }
184
Marie Janssen59804562016-12-28 14:13:21 -0800185 public String toString() {
Jack He8caab152018-03-02 13:08:36 -0800186 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ")
187 + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800188 }
189
190 }
191
Jack He8caab152018-03-02 13:08:36 -0800192 private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
193 private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
Marie Janssene54b4222017-03-16 18:10:59 -0700194 private int mCrashes;
Marie Janssen12a35012017-06-26 07:21:03 -0700195 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800196
197 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800198 // synchronize with broadcast receiver.
199 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800200 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800201
202 // Map of apps registered to keep BLE scanning on.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800203 private Map<IBinder, ClientDeathRecipient> mBleApps =
204 new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
Marie Janssen59804562016-12-28 14:13:21 -0800205
Zhihai Xu40874a02012-10-08 17:57:03 -0700206 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700207 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800208 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200209 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700210
Benjamin Franze8b98922014-11-12 15:57:54 +0000211 // Save a ProfileServiceConnections object for each of the bound
212 // bluetooth profile services
Jack He8caab152018-03-02 13:08:36 -0800213 private final Map<Integer, ProfileServiceConnections> mProfileServices = new HashMap<>();
Benjamin Franze8b98922014-11-12 15:57:54 +0000214
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700215 private final boolean mPermissionReviewRequired;
216
Marie Janssen59804562016-12-28 14:13:21 -0800217 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700218 @Override
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800219 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
220 Message msg =
221 mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
fredcbf072a72012-05-09 16:52:50 -0700222 mHandler.sendMessage(msg);
223 }
224 };
225
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100226 private final UserRestrictionsListener mUserRestrictionsListener =
227 new UserRestrictionsListener() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800228 @Override
229 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
230 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700231
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800232 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
233 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
234 updateOppLauncherComponentState(userId,
235 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING));
236 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100237
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800238 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
239 if (userId == UserHandle.USER_SYSTEM
240 && UserRestrictionsUtils.restrictionsChanged(prevRestrictions,
241 newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
242 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
243 UserManager.DISALLOW_BLUETOOTH)) {
244 updateOppLauncherComponentState(userId, true); // Sharing disallowed
Jack He8caab152018-03-02 13:08:36 -0800245 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED,
246 mContext.getPackageName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800247 } else {
248 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
249 UserManager.DISALLOW_BLUETOOTH_SHARING));
250 }
251 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100252 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800253 };
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100254
Ajay Panicker467bc042017-02-22 12:23:15 -0800255 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
256 @Override
257 public void onChange(boolean unused) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800258 synchronized (this) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800259 if (isBluetoothPersistedStateOn()) {
260 if (isAirplaneModeOn()) {
261 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
262 } else {
263 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
264 }
265 }
266
267 int st = BluetoothAdapter.STATE_OFF;
268 try {
269 mBluetoothLock.readLock().lock();
270 if (mBluetooth != null) {
271 st = mBluetooth.getState();
272 }
273 } catch (RemoteException e) {
274 Slog.e(TAG, "Unable to call getState", e);
275 return;
276 } finally {
277 mBluetoothLock.readLock().unlock();
278 }
279
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800280 Slog.d(TAG,
281 "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
Rene Mayrhofer0860f292018-11-28 11:32:40 -0800282 st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
Ajay Panicker467bc042017-02-22 12:23:15 -0800283
284 if (isAirplaneModeOn()) {
285 // Clear registered LE apps to force shut-off
286 clearBleApps();
287
288 // If state is BLE_ON make sure we trigger disableBLE
289 if (st == BluetoothAdapter.STATE_BLE_ON) {
290 try {
291 mBluetoothLock.readLock().lock();
292 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700293 addActiveLog(
294 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
295 mContext.getPackageName(), false);
Ajay Panicker467bc042017-02-22 12:23:15 -0800296 mBluetooth.onBrEdrDown();
297 mEnable = false;
298 mEnableExternal = false;
299 }
300 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800301 Slog.e(TAG, "Unable to call onBrEdrDown", e);
Ajay Panicker467bc042017-02-22 12:23:15 -0800302 } finally {
303 mBluetoothLock.readLock().unlock();
304 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800305 } else if (st == BluetoothAdapter.STATE_ON) {
Jack He8caab152018-03-02 13:08:36 -0800306 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
307 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800308 }
309 } else if (mEnableExternal) {
Jack He8caab152018-03-02 13:08:36 -0800310 sendEnableMsg(mQuietEnableExternal,
311 BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
312 mContext.getPackageName());
Ajay Panicker467bc042017-02-22 12:23:15 -0800313 }
314 }
315 }
316 };
317
fredcbf072a72012-05-09 16:52:50 -0700318 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700319 @Override
320 public void onReceive(Context context, Intent intent) {
321 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700322 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700323 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800324 if (DBG) {
325 Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
326 }
fredc0f420372012-04-12 00:02:00 -0700327 if (newName != null) {
328 storeNameAndAddress(newName, null);
329 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700330 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
331 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
332 if (newAddress != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800333 if (DBG) {
334 Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
335 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700336 storeNameAndAddress(null, newAddress);
337 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800338 if (DBG) {
339 Slog.e(TAG, "No Bluetooth Adapter address parameter found");
340 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700341 }
Stanley Tng873b5702017-05-01 21:27:31 -0700342 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
343 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
344 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
345 // The Bluetooth On state may be changed during system restore.
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800346 final String prevValue =
347 intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE);
348 final String newValue = intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE);
Stanley Tng873b5702017-05-01 21:27:31 -0700349
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800350 if (DBG) {
351 Slog.d(TAG,
352 "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" + prevValue
353 + ", newValue=" + newValue);
354 }
Stanley Tng873b5702017-05-01 21:27:31 -0700355
356 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
357 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800358 newValue.equals("0") ? RESTORE_SETTING_TO_OFF
359 : RESTORE_SETTING_TO_ON, 0);
Stanley Tng873b5702017-05-01 21:27:31 -0700360 mHandler.sendMessage(msg);
361 }
362 }
fredc0f420372012-04-12 00:02:00 -0700363 }
364 }
365 };
366
367 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700368 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700369
fredc0f420372012-04-12 00:02:00 -0700370 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700371
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800372 mPermissionReviewRequired = context.getResources()
373 .getBoolean(com.android.internal.R.bool.config_permissionReviewRequired);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700374
Marie Janssene54b4222017-03-16 18:10:59 -0700375 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700376 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800377 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800378 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700379 mBinding = false;
380 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700381 mEnable = false;
382 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800383 mQuietEnableExternal = false;
384 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700385 mAddress = null;
386 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800387 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700388 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700389 // Observe BLE scan only mode settings change.
390 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700391 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
392 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700393
Stanley Tngcbfcbd12018-06-19 08:48:10 -0700394 // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
395 boolean isHearingAidEnabled;
396 String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
397 if (!TextUtils.isEmpty(value)) {
398 isHearingAidEnabled = Boolean.parseBoolean(value);
399 Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
400 FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
401 }
402
Stanley Tng873b5702017-05-01 21:27:31 -0700403 IntentFilter filter = new IntentFilter();
404 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
405 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
406 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700407 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700408 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700409
fredc0f420372012-04-12 00:02:00 -0700410 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800411 if (isBluetoothPersistedStateOn()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800412 if (DBG) {
413 Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
414 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800415 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700416 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200417
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800418 String airplaneModeRadios =
419 Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
420 if (airplaneModeRadios == null || airplaneModeRadios.contains(
421 Settings.Global.RADIO_BLUETOOTH)) {
Ajay Panicker467bc042017-02-22 12:23:15 -0800422 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800423 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
424 mAirplaneModeObserver);
Ajay Panicker467bc042017-02-22 12:23:15 -0800425 }
426
Marie Janssen59804562016-12-28 14:13:21 -0800427 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200428 try {
Arthur Hsuf3f95a92018-01-11 16:46:22 -0800429 // Check if device is configured with no home screen, which implies no SystemUI.
430 boolean noHome = mContext.getResources().getBoolean(R.bool.config_noHomeScreen);
431 if (!noHome) {
432 systemUiUid = mContext.getPackageManager()
433 .getPackageUidAsUser("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY,
434 UserHandle.USER_SYSTEM);
435 }
436 Slog.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid));
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200437 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700438 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700439 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200440 }
Marie Janssen59804562016-12-28 14:13:21 -0800441 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700442 }
443
fredc649fe492012-04-19 01:07:18 -0700444 /**
445 * Returns true if airplane mode is currently on
446 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800447 private boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700448 return Settings.Global.getInt(mContext.getContentResolver(),
449 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700450 }
451
Arthur Hsu2433baf2018-01-11 11:05:11 -0800452 private boolean supportBluetoothPersistedState() {
453 return mContext.getResources().getBoolean(R.bool.config_supportBluetoothPersistedState);
454 }
455
fredc649fe492012-04-19 01:07:18 -0700456 /**
457 * Returns true if the Bluetooth saved state is "on"
458 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800459 private boolean isBluetoothPersistedStateOn() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800460 if (!supportBluetoothPersistedState()) {
461 return false;
462 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800463 int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
464 if (DBG) {
465 Slog.d(TAG, "Bluetooth persisted state: " + state);
466 }
Marie Janssen9fa24912016-10-18 10:04:24 -0700467 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800468 }
469
470 /**
471 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
472 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800473 private boolean isBluetoothPersistedStateOnBluetooth() {
Arthur Hsu2433baf2018-01-11 11:05:11 -0800474 if (!supportBluetoothPersistedState()) {
475 return false;
476 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800477 return Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON,
478 BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700479 }
480
481 /**
482 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700483 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800484 private void persistBluetoothSetting(int value) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800485 if (DBG) {
486 Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
487 }
Marie Janssenfa630682016-12-15 13:51:30 -0800488 // waive WRITE_SECURE_SETTINGS permission check
489 long callingIdentity = Binder.clearCallingIdentity();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800490 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
Marie Janssenfa630682016-12-15 13:51:30 -0800491 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700492 }
493
494 /**
495 * Returns true if the Bluetooth Adapter's name and address is
496 * locally cached
497 * @return
498 */
fredc0f420372012-04-12 00:02:00 -0700499 private boolean isNameAndAddressSet() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800500 return mName != null && mAddress != null && mName.length() > 0 && mAddress.length() > 0;
fredc0f420372012-04-12 00:02:00 -0700501 }
502
fredc649fe492012-04-19 01:07:18 -0700503 /**
504 * Retrieve the Bluetooth Adapter's name and address and save it in
505 * in the local cache
506 */
fredc0f420372012-04-12 00:02:00 -0700507 private void loadStoredNameAndAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800508 if (DBG) {
509 Slog.d(TAG, "Loading stored name and address");
510 }
511 if (mContext.getResources()
512 .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation)
513 && Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0)
514 == 0) {
Zhihai Xud31c3222012-10-31 16:08:57 -0700515 // if the valid flag is not set, don't load the address and name
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800516 if (DBG) {
517 Slog.d(TAG, "invalid bluetooth name and address stored");
518 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700519 return;
520 }
fredc0f420372012-04-12 00:02:00 -0700521 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
522 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800523 if (DBG) {
524 Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
525 }
fredc0f420372012-04-12 00:02:00 -0700526 }
527
fredc649fe492012-04-19 01:07:18 -0700528 /**
529 * Save the Bluetooth name and address in the persistent store.
530 * Only non-null values will be saved.
531 * @param name
532 * @param address
533 */
fredc0f420372012-04-12 00:02:00 -0700534 private void storeNameAndAddress(String name, String address) {
535 if (name != null) {
536 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700537 mName = name;
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800538 if (DBG) {
539 Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getString(mContentResolver,
540 SECURE_SETTINGS_BLUETOOTH_NAME));
541 }
fredc0f420372012-04-12 00:02:00 -0700542 }
543
544 if (address != null) {
545 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800546 mAddress = address;
547 if (DBG) {
548 Slog.d(TAG,
549 "Stored Bluetoothaddress: " + Settings.Secure.getString(mContentResolver,
550 SECURE_SETTINGS_BLUETOOTH_ADDRESS));
551 }
fredc0f420372012-04-12 00:02:00 -0700552 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700553
554 if ((name != null) && (address != null)) {
555 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
556 }
fredc0f420372012-04-12 00:02:00 -0700557 }
558
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800559 public IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700560 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700561 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700562 return null;
563 }
fredc0f420372012-04-12 00:02:00 -0700564 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
565 msg.obj = callback;
566 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700567
568 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700569 }
570
571 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700572 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700573 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700574 return;
575 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800576 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
fredc0f420372012-04-12 00:02:00 -0700577 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
578 msg.obj = callback;
579 mHandler.sendMessage(msg);
580 }
581
582 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800583 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800584 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800585 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
586 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800587 }
fredc0f420372012-04-12 00:02:00 -0700588 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
589 msg.obj = callback;
590 mHandler.sendMessage(msg);
591 }
592
593 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800594 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800595 if (callback == null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800596 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
597 return;
Marie Janssencb21ad72016-12-13 10:51:02 -0800598 }
fredc0f420372012-04-12 00:02:00 -0700599 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
600 msg.obj = callback;
601 mHandler.sendMessage(msg);
602 }
603
604 public boolean isEnabled() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800605 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
606 Slog.w(TAG, "isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700607 return false;
608 }
609
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700610 try {
611 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800612 if (mBluetooth != null) {
613 return mBluetooth.isEnabled();
614 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700615 } catch (RemoteException e) {
616 Slog.e(TAG, "isEnabled()", e);
617 } finally {
618 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700619 }
620 return false;
621 }
622
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700623 public int getState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800624 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800625 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700626 return BluetoothAdapter.STATE_OFF;
627 }
628
629 try {
630 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800631 if (mBluetooth != null) {
632 return mBluetooth.getState();
633 }
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700634 } catch (RemoteException e) {
635 Slog.e(TAG, "getState()", e);
636 } finally {
637 mBluetoothLock.readLock().unlock();
638 }
639 return BluetoothAdapter.STATE_OFF;
640 }
641
Nitin Arorad055adb2015-03-02 15:03:51 -0800642 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800643 private String mPackageName;
644
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800645 ClientDeathRecipient(String packageName) {
Marie Janssen59804562016-12-28 14:13:21 -0800646 mPackageName = packageName;
647 }
648
Nitin Arorad055adb2015-03-02 15:03:51 -0800649 public void binderDied() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800650 if (DBG) {
651 Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800652 }
Stanley Tng2c5fd282018-03-19 13:06:45 -0700653
654 for (Map.Entry<IBinder, ClientDeathRecipient> entry : mBleApps.entrySet()) {
655 IBinder token = entry.getKey();
656 ClientDeathRecipient deathRec = entry.getValue();
657 if (deathRec.equals(this)) {
Stanley Tng600109c2018-03-20 16:54:27 -0700658 updateBleAppCount(token, false, mPackageName);
Stanley Tng2c5fd282018-03-19 13:06:45 -0700659 break;
660 }
661 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800662 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800663
Marie Janssen59804562016-12-28 14:13:21 -0800664 public String getPackageName() {
665 return mPackageName;
666 }
667 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800668
Wei Wang67d84162015-04-26 17:04:29 -0700669 @Override
670 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700671 if (isAirplaneModeOn() && !mEnable) {
672 return false;
673 }
Wei Wang67d84162015-04-26 17:04:29 -0700674 try {
Jack He8caab152018-03-02 13:08:36 -0800675 return Settings.Global.getInt(mContentResolver,
676 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0;
Wei Wang67d84162015-04-26 17:04:29 -0700677 } catch (SettingNotFoundException e) {
678 }
679 return false;
680 }
681
Wei Wange4a744b2015-06-11 17:50:29 -0700682 // Monitor change of BLE scan only mode settings.
683 private void registerForBleScanModeChange() {
684 ContentObserver contentObserver = new ContentObserver(null) {
685 @Override
686 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800687 if (isBleScanAlwaysAvailable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800688 // Nothing to do
689 return;
Marie Janssen2977c3e2016-11-09 12:01:24 -0800690 }
691 // BLE scan is not available.
692 disableBleScanMode();
693 clearBleApps();
694 try {
695 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800696 if (mBluetooth != null) {
Hansong Zhang276eb1b2018-04-23 11:17:17 -0700697 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
698 mContext.getPackageName(), false);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800699 mBluetooth.onBrEdrDown();
700 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800701 } catch (RemoteException e) {
702 Slog.e(TAG, "error when disabling bluetooth", e);
703 } finally {
704 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700705 }
706 }
707 };
708
709 mContentResolver.registerContentObserver(
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800710 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), false,
711 contentObserver);
Wei Wange4a744b2015-06-11 17:50:29 -0700712 }
713
714 // Disable ble scan only mode.
715 private void disableBleScanMode() {
716 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700717 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700718 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800719 if (DBG) {
720 Slog.d(TAG, "Reseting the mEnable flag for clean disable");
721 }
Wei Wange4a744b2015-06-11 17:50:29 -0700722 mEnable = false;
723 }
724 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700725 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700726 } finally {
727 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700728 }
729 }
730
Marie Janssen59804562016-12-28 14:13:21 -0800731 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
732 ClientDeathRecipient r = mBleApps.get(token);
733 if (r == null && enable) {
734 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
735 try {
736 token.linkToDeath(deathRec, 0);
737 } catch (RemoteException ex) {
738 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 }
Marie Janssen59804562016-12-28 14:13:21 -0800740 mBleApps.put(token, deathRec);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800741 if (DBG) {
742 Slog.d(TAG, "Registered for death of " + packageName);
743 }
Marie Janssen59804562016-12-28 14:13:21 -0800744 } else if (!enable && r != null) {
745 // Unregister death recipient as the app goes away.
746 token.unlinkToDeath(r, 0);
747 mBleApps.remove(token);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800748 if (DBG) {
749 Slog.d(TAG, "Unregistered for death of " + packageName);
750 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800751 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800752 int appCount = mBleApps.size();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800753 if (DBG) {
754 Slog.d(TAG, appCount + " registered Ble Apps");
755 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800756 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700757 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800758 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800759 if (appCount == 0 && !mEnableExternal) {
760 sendBrEdrDownCallback();
761 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800762 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800763 }
764
Wei Wange4a744b2015-06-11 17:50:29 -0700765 // Clear all apps using BLE scan only mode.
766 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800767 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700768 }
769
Marie Janssen59804562016-12-28 14:13:21 -0800770 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800771 public boolean isBleAppPresent() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800772 if (DBG) {
773 Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
774 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800775 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
777
778 /**
Myles Watson304ebf22018-05-11 08:47:24 -0700779 * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
Nitin Arorad055adb2015-03-02 15:03:51 -0800780 */
Myles Watson304ebf22018-05-11 08:47:24 -0700781 private void continueFromBleOnState() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800782 if (DBG) {
Myles Watson304ebf22018-05-11 08:47:24 -0700783 Slog.d(TAG, "continueFromBleOnState()");
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800784 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700785 try {
786 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800787 if (mBluetooth == null) {
Myles Watson304ebf22018-05-11 08:47:24 -0700788 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
Marie Janssenfa630682016-12-15 13:51:30 -0800789 return;
790 }
791 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
792 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800793 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800794 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800795 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700796 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800797 Slog.e(TAG, "Unable to call onServiceUp", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700798 } finally {
799 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800800 }
801 }
802
803 /**
804 * Inform BluetoothAdapter instances that BREDR part is down
805 * and turn off all service and stack if no LE app needs it
806 */
807 private void sendBrEdrDownCallback() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800808 if (DBG) {
809 Slog.d(TAG, "Calling sendBrEdrDownCallback callbacks");
810 }
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700811
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700812 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700813 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700814 return;
815 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800816
Martin Brabhamc2b06222017-02-27 16:55:07 -0800817 if (isBleAppPresent()) {
818 // Need to stay at BLE ON. Disconnect all Gatt connections
819 try {
820 mBluetoothGatt.unregAll();
821 } catch (RemoteException e) {
822 Slog.e(TAG, "Unable to disconnect all apps.", e);
823 }
824 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800825 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700826 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800827 if (mBluetooth != null) {
828 mBluetooth.onBrEdrDown();
829 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700830 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700831 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700832 } finally {
833 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800834 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800835 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800836
Nitin Arorad055adb2015-03-02 15:03:51 -0800837 }
838
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800839 public boolean enableNoAutoConnect(String packageName) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100840 if (isBluetoothDisallowed()) {
841 if (DBG) {
842 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
843 }
844 return false;
845 }
846
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700847 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800848 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700849
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700850 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800851 Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
852 + mBinding);
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700853 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800854 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
855
856 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700857 throw new SecurityException("no permission to enable Bluetooth quietly");
858 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800859
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800860 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800861 mQuietEnableExternal = true;
862 mEnableExternal = true;
Jack He8caab152018-03-02 13:08:36 -0800863 sendEnableMsg(true,
864 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800865 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700866 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700867 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700868
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700869 public boolean enable(String packageName) throws RemoteException {
870 final int callingUid = Binder.getCallingUid();
871 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
872
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100873 if (isBluetoothDisallowed()) {
874 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800875 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100876 }
877 return false;
878 }
879
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700880 if (!callerSystem) {
881 if (!checkIfCallerIsForegroundUser()) {
882 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
883 return false;
884 }
885
886 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
887 "Need BLUETOOTH ADMIN permission");
888
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800889 if (!isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
890 callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700891 return false;
892 }
fredcf2458862012-04-16 15:18:27 -0700893 }
894
Zhihai Xu401202b2012-12-03 11:36:21 -0800895 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800896 Slog.d(TAG, "enable(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = "
897 + mBinding + " mState = " + BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700898 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800899
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800900 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800901 mQuietEnableExternal = false;
902 mEnableExternal = true;
903 // waive WRITE_SECURE_SETTINGS permission check
Jack He8caab152018-03-02 13:08:36 -0800904 sendEnableMsg(false,
905 BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800906 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800907 if (DBG) {
908 Slog.d(TAG, "enable returning");
909 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800910 return true;
fredc0f420372012-04-12 00:02:00 -0700911 }
912
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700913 public boolean disable(String packageName, boolean persist) throws RemoteException {
914 final int callingUid = Binder.getCallingUid();
915 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700916
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700917 if (!callerSystem) {
918 if (!checkIfCallerIsForegroundUser()) {
919 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
920 return false;
921 }
922
923 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
924 "Need BLUETOOTH ADMIN permission");
925
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800926 if (isEnabled() && mPermissionReviewRequired && startConsentUiIfNeeded(packageName,
927 callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700928 return false;
929 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700930 }
931
fredcf2458862012-04-16 15:18:27 -0700932 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800933 Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
Matthew Xiecdce0b92012-07-12 19:06:15 -0700934 }
fredcf2458862012-04-16 15:18:27 -0700935
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800936 synchronized (mReceiver) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800937 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800938 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800939 }
940 mEnableExternal = false;
Jack He8caab152018-03-02 13:08:36 -0800941 sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
942 packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800943 }
fredc0f420372012-04-12 00:02:00 -0700944 return true;
945 }
946
baishengf62d8692018-01-25 18:07:24 +0800947 private boolean startConsentUiIfNeeded(String packageName,
948 int callingUid, String intentAction) throws RemoteException {
949 if (checkBluetoothPermissionWhenPermissionReviewRequired()) {
950 return false;
951 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700952 try {
953 // Validate the package only if we are going to use it
954 ApplicationInfo applicationInfo = mContext.getPackageManager()
955 .getApplicationInfoAsUser(packageName,
956 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
957 UserHandle.getUserId(callingUid));
958 if (applicationInfo.uid != callingUid) {
baishengf62d8692018-01-25 18:07:24 +0800959 throw new SecurityException("Package " + packageName
960 + " not in uid " + callingUid);
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700961 }
962
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000963 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000964 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
Myles Watsonb5cd11a2017-11-27 16:42:11 -0800965 intent.setFlags(
966 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000967 try {
968 mContext.startActivity(intent);
969 } catch (ActivityNotFoundException e) {
970 // Shouldn't happen
971 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
972 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700973 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000974 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700975 } catch (PackageManager.NameNotFoundException e) {
976 throw new RemoteException(e.getMessage());
977 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700978 }
979
baishengf62d8692018-01-25 18:07:24 +0800980 /**
981 * Check if the caller must still pass permission check or if the caller is exempted
982 * from the consent UI via the MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED check.
983 *
984 * Commands from some callers may be exempted from triggering the consent UI when
985 * enabling bluetooth. This exemption is checked via the
986 * MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED and allows calls to skip
987 * the consent UI where it may otherwise be required.
988 *
989 * @hide
990 */
991 private boolean checkBluetoothPermissionWhenPermissionReviewRequired() {
992 if (!mPermissionReviewRequired) {
993 return false;
994 }
995 int result = mContext.checkCallingPermission(
996 android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED);
997 return result == PackageManager.PERMISSION_GRANTED;
998 }
999
fredc649fe492012-04-19 01:07:18 -07001000 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -07001001 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001002 Slog.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding
1003 + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -07001004 }
1005
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001006 try {
1007 mBluetoothLock.writeLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001008 if (mUnbinding) {
1009 return;
1010 }
fredc0f420372012-04-12 00:02:00 -07001011 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001012 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -07001013 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -07001014 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001015 //Unregister callback object
1016 try {
1017 mBluetooth.unregisterCallback(mBluetoothCallback);
1018 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001019 Slog.e(TAG, "Unable to unregister BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001020 }
Marie Janssen9db28eb2016-01-12 16:05:15 -08001021 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -07001022 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -07001023 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -07001024 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -07001025 mBinding = false;
fredcf2458862012-04-16 15:18:27 -07001026 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001027 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -07001028 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001029 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001030 } finally {
1031 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -07001032 }
1033 }
1034
Matthew Xieddf7e472013-03-01 18:41:02 -08001035 public IBluetoothGatt getBluetoothGatt() {
1036 // sync protection
1037 return mBluetoothGatt;
1038 }
1039
Benjamin Franze8b98922014-11-12 15:57:54 +00001040 @Override
1041 public boolean bindBluetoothProfileService(int bluetoothProfile,
1042 IBluetoothProfileServiceConnection proxy) {
1043 if (!mEnable) {
1044 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001045 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile
1046 + ", while Bluetooth was disabled");
Benjamin Franze8b98922014-11-12 15:57:54 +00001047 }
1048 return false;
1049 }
1050 synchronized (mProfileServices) {
1051 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1052 if (psc == null) {
1053 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001054 Slog.d(TAG, "Creating new ProfileServiceConnections object for" + " profile: "
1055 + bluetoothProfile);
Benjamin Franze8b98922014-11-12 15:57:54 +00001056 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001057
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001058 if (bluetoothProfile != BluetoothProfile.HEADSET) {
1059 return false;
1060 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001061
1062 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +00001063 psc = new ProfileServiceConnections(intent);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001064 if (!psc.bindService()) {
1065 return false;
1066 }
Benjamin Franz5b614592014-12-09 18:58:45 +00001067
Benjamin Franze8b98922014-11-12 15:57:54 +00001068 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +00001069 }
1070 }
1071
1072 // Introducing a delay to give the client app time to prepare
1073 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
1074 addProxyMsg.arg1 = bluetoothProfile;
1075 addProxyMsg.obj = proxy;
1076 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
1077 return true;
1078 }
1079
1080 @Override
1081 public void unbindBluetoothProfileService(int bluetoothProfile,
1082 IBluetoothProfileServiceConnection proxy) {
1083 synchronized (mProfileServices) {
1084 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
1085 if (psc == null) {
1086 return;
1087 }
1088 psc.removeProxy(proxy);
1089 }
1090 }
1091
1092 private void unbindAllBluetoothProfileServices() {
1093 synchronized (mProfileServices) {
1094 for (Integer i : mProfileServices.keySet()) {
1095 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001096 try {
1097 mContext.unbindService(psc);
1098 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001099 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001100 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001101 psc.removeAllProxies();
1102 }
1103 mProfileServices.clear();
1104 }
1105 }
1106
1107 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001108 * Send enable message and set adapter name and address. Called when the boot phase becomes
1109 * PHASE_SYSTEM_SERVICES_READY.
1110 */
1111 public void handleOnBootPhase() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001112 if (DBG) {
1113 Slog.d(TAG, "Bluetooth boot completed");
1114 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001115 UserManagerInternal userManagerInternal =
1116 LocalServices.getService(UserManagerInternal.class);
1117 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001118 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001119 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001120 return;
1121 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001122 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001123 if (DBG) {
1124 Slog.d(TAG, "Auto-enabling Bluetooth.");
1125 }
Jack He8caab152018-03-02 13:08:36 -08001126 sendEnableMsg(mQuietEnableExternal,
1127 BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT,
1128 mContext.getPackageName());
Ajay Panickerbf796d82016-03-11 13:47:20 -08001129 } else if (!isNameAndAddressSet()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001130 if (DBG) {
1131 Slog.d(TAG, "Getting adapter name and address");
1132 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001133 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1134 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001135 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001136 }
1137
1138 /**
1139 * Called when switching to a different foreground user.
1140 */
1141 public void handleOnSwitchUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001142 if (DBG) {
1143 Slog.d(TAG, "User " + userHandle + " switched");
1144 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001145 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1146 }
1147
1148 /**
1149 * Called when user is unlocked.
1150 */
1151 public void handleOnUnlockUser(int userHandle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001152 if (DBG) {
1153 Slog.d(TAG, "User " + userHandle + " unlocked");
1154 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001155 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001156 }
1157
1158 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001159 * This class manages the clients connected to a given ProfileService
1160 * and maintains the connection with that service.
1161 */
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001162 private final class ProfileServiceConnections
1163 implements ServiceConnection, IBinder.DeathRecipient {
Benjamin Franze8b98922014-11-12 15:57:54 +00001164 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001165 new RemoteCallbackList<IBluetoothProfileServiceConnection>();
Benjamin Franze8b98922014-11-12 15:57:54 +00001166 IBinder mService;
1167 ComponentName mClassName;
1168 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001169 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001170
1171 ProfileServiceConnections(Intent intent) {
1172 mService = null;
1173 mClassName = null;
1174 mIntent = intent;
1175 }
1176
Benjamin Franz5b614592014-12-09 18:58:45 +00001177 private boolean bindService() {
jonerlin37fc85d2018-08-09 16:39:43 +08001178 int state = BluetoothAdapter.STATE_OFF;
1179 try {
1180 mBluetoothLock.readLock().lock();
1181 if (mBluetooth != null) {
1182 state = mBluetooth.getState();
1183 }
1184 } catch (RemoteException e) {
1185 Slog.e(TAG, "Unable to call getState", e);
1186 return false;
1187 } finally {
1188 mBluetoothLock.readLock().unlock();
1189 }
1190
1191 if (!mEnable || state != BluetoothAdapter.STATE_ON) {
1192 if (DBG) {
1193 Slog.d(TAG, "Unable to bindService while Bluetooth is disabled");
1194 }
1195 return false;
1196 }
1197
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001198 if (mIntent != null && mService == null && doBind(mIntent, this, 0,
1199 UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001200 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1201 msg.obj = this;
1202 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001203 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001204 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001205 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001206 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001207 }
1208
1209 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1210 mProxies.register(proxy);
1211 if (mService != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001212 try {
Benjamin Franze8b98922014-11-12 15:57:54 +00001213 proxy.onServiceConnected(mClassName, mService);
1214 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001215 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001216 }
1217 } else {
1218 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1219 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1220 msg.obj = this;
1221 mHandler.sendMessage(msg);
1222 }
1223 }
1224 }
1225
1226 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1227 if (proxy != null) {
1228 if (mProxies.unregister(proxy)) {
1229 try {
1230 proxy.onServiceDisconnected(mClassName);
1231 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001232 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001233 }
1234 }
1235 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001236 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001237 }
1238 }
1239
1240 private void removeAllProxies() {
1241 onServiceDisconnected(mClassName);
1242 mProxies.kill();
1243 }
1244
1245 @Override
1246 public void onServiceConnected(ComponentName className, IBinder service) {
1247 // remove timeout message
1248 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1249 mService = service;
1250 mClassName = className;
1251 try {
1252 mService.linkToDeath(this, 0);
1253 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001254 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001255 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001256
1257 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001258 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001259 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001260 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001261 mInvokingProxyCallbacks = true;
1262
1263 final int n = mProxies.beginBroadcast();
1264 try {
1265 for (int i = 0; i < n; i++) {
1266 try {
1267 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1268 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001269 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001270 }
1271 }
1272 } finally {
1273 mProxies.finishBroadcast();
1274 mInvokingProxyCallbacks = false;
1275 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001276 }
1277
1278 @Override
1279 public void onServiceDisconnected(ComponentName className) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001280 if (mService == null) {
1281 return;
1282 }
Chienyuan177156b2018-12-18 10:40:25 +08001283 try {
1284 mService.unlinkToDeath(this, 0);
1285 } catch (NoSuchElementException e) {
1286 Log.e(TAG, "error unlinking to death", e);
1287 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001288 mService = null;
1289 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001290
1291 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001292 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001293 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001294 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001295 mInvokingProxyCallbacks = true;
1296
1297 final int n = mProxies.beginBroadcast();
1298 try {
1299 for (int i = 0; i < n; i++) {
1300 try {
1301 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1302 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001303 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001304 }
1305 }
1306 } finally {
1307 mProxies.finishBroadcast();
1308 mInvokingProxyCallbacks = false;
1309 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001310 }
1311
1312 @Override
1313 public void binderDied() {
1314 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001315 Slog.w(TAG, "Profile service for profile: " + mClassName + " died.");
Benjamin Franze8b98922014-11-12 15:57:54 +00001316 }
1317 onServiceDisconnected(mClassName);
1318 // Trigger rebind
1319 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1320 msg.obj = this;
1321 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1322 }
1323 }
1324
fredcbf072a72012-05-09 16:52:50 -07001325 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001326 try {
1327 int n = mStateChangeCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001328 if (DBG) {
1329 Slog.d(TAG, "Broadcasting onBluetoothStateChange(" + isUp + ") to " + n
1330 + " receivers.");
1331 }
1332 for (int i = 0; i < n; i++) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001333 try {
1334 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1335 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001336 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001337 }
fredcbf072a72012-05-09 16:52:50 -07001338 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001339 } finally {
1340 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001341 }
fredcbf072a72012-05-09 16:52:50 -07001342 }
1343
1344 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001345 * Inform BluetoothAdapter instances that Adapter service is up
1346 */
1347 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001348 try {
1349 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001350 Slog.d(TAG, "Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
1351 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001352 try {
1353 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001354 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001355 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001356 }
1357 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001358 } finally {
1359 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001360 }
1361 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001362
Zhihai Xu40874a02012-10-08 17:57:03 -07001363 /**
fredcbf072a72012-05-09 16:52:50 -07001364 * Inform BluetoothAdapter instances that Adapter service is down
1365 */
1366 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001367 try {
1368 int n = mCallbacks.beginBroadcast();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001369 Slog.d(TAG, "Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
1370 for (int i = 0; i < n; i++) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001371 try {
1372 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001373 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001374 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001375 }
1376 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001377 } finally {
1378 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001379 }
1380 }
Svet Ganov408abf72015-05-12 19:13:36 -07001381
fredc0f420372012-04-12 00:02:00 -07001382 public String getAddress() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001383 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001384
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001385 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1386 Slog.w(TAG, "getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001387 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001388 }
1389
Svet Ganov408abf72015-05-12 19:13:36 -07001390 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1391 != PackageManager.PERMISSION_GRANTED) {
1392 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1393 }
1394
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001395 try {
1396 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001397 if (mBluetooth != null) {
1398 return mBluetooth.getAddress();
1399 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001400 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001401 Slog.e(TAG,
1402 "getAddress(): Unable to retrieve address remotely. Returning cached address",
1403 e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001404 } finally {
1405 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001406 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001407
Matthew Xiecdce0b92012-07-12 19:06:15 -07001408 // mAddress is accessed from outside.
1409 // It is alright without a lock. Here, bluetooth is off, no other thread is
1410 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001411 return mAddress;
1412 }
fredc649fe492012-04-19 01:07:18 -07001413
fredc0f420372012-04-12 00:02:00 -07001414 public String getName() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001415 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001416
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001417 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
1418 Slog.w(TAG, "getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001419 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001420 }
1421
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001422 try {
1423 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001424 if (mBluetooth != null) {
1425 return mBluetooth.getName();
1426 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001427 } catch (RemoteException e) {
1428 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1429 } finally {
1430 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001431 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001432
Matthew Xiecdce0b92012-07-12 19:06:15 -07001433 // mName is accessed from outside.
1434 // It alright without a lock. Here, bluetooth is off, no other thread is
1435 // changing mName
fredc0f420372012-04-12 00:02:00 -07001436 return mName;
1437 }
1438
fredc0f420372012-04-12 00:02:00 -07001439 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001440 public void onServiceConnected(ComponentName componentName, IBinder service) {
1441 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001442 if (DBG) {
1443 Slog.d(TAG, "BluetoothServiceConnection: " + name);
1444 }
fredc0f420372012-04-12 00:02:00 -07001445 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001446 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001447 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001448 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001449 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1450 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001451 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001452 return;
1453 }
fredc0f420372012-04-12 00:02:00 -07001454 msg.obj = service;
1455 mHandler.sendMessage(msg);
1456 }
1457
Marie Janssencb21ad72016-12-13 10:51:02 -08001458 public void onServiceDisconnected(ComponentName componentName) {
1459 // Called if we unexpectedly disconnect.
1460 String name = componentName.getClassName();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001461 if (DBG) {
1462 Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
1463 }
fredc0f420372012-04-12 00:02:00 -07001464 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001465 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001466 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001467 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001468 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1469 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001470 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001471 return;
1472 }
fredc0f420372012-04-12 00:02:00 -07001473 mHandler.sendMessage(msg);
1474 }
1475 }
1476
1477 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1478
Zhihai Xu40874a02012-10-08 17:57:03 -07001479 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001480 boolean mGetNameAddressOnly = false;
1481
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001482 BluetoothHandler(Looper looper) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001483 super(looper);
1484 }
1485
fredc0f420372012-04-12 00:02:00 -07001486 @Override
1487 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001488 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001489 case MESSAGE_GET_NAME_AND_ADDRESS:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001490 if (DBG) {
1491 Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
1492 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001493 try {
1494 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001495 if ((mBluetooth == null) && (!mBinding)) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001496 if (DBG) {
1497 Slog.d(TAG, "Binding to service to get name and address");
1498 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001499 mGetNameAddressOnly = true;
1500 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1501 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1502 Intent i = new Intent(IBluetooth.class.getName());
1503 if (!doBind(i, mConnection,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001504 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1505 UserHandle.CURRENT)) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001506 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1507 } else {
1508 mBinding = true;
1509 }
1510 } else if (mBluetooth != null) {
1511 try {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001512 storeNameAndAddress(mBluetooth.getName(), mBluetooth.getAddress());
Ajay Panicker4bb48302016-03-31 14:14:27 -07001513 } catch (RemoteException re) {
1514 Slog.e(TAG, "Unable to grab names", re);
1515 }
1516 if (mGetNameAddressOnly && !mEnable) {
1517 unbindAndFinish();
1518 }
1519 mGetNameAddressOnly = false;
1520 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001521 } finally {
1522 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001523 }
1524 break;
1525
Matthew Xiecdce0b92012-07-12 19:06:15 -07001526 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001527 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001528 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001529 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001530 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1531 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001532
1533 // Use service interface to get the exact state
1534 try {
1535 mBluetoothLock.readLock().lock();
1536 if (mBluetooth != null) {
1537 int state = mBluetooth.getState();
1538 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001539 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001540 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001541 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001542 break;
1543 }
1544 }
1545 } catch (RemoteException e) {
1546 Slog.e(TAG, "", e);
1547 } finally {
1548 mBluetoothLock.readLock().unlock();
1549 }
1550
1551 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001552 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001553 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001554 } else {
1555 //
1556 // We need to wait until transitioned to STATE_OFF and
1557 // the previous Bluetooth process has exited. The
1558 // waiting period has three components:
1559 // (a) Wait until the local state is STATE_OFF. This
1560 // is accomplished by "waitForOnOff(false, true)".
1561 // (b) Wait until the STATE_OFF state is updated to
1562 // all components.
1563 // (c) Wait until the Bluetooth process exits, and
1564 // ActivityManager detects it.
1565 // The waiting for (b) and (c) is accomplished by
1566 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1567 // message. On slower devices, that delay needs to be
1568 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1569 //
1570 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001571 Message restartMsg =
1572 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1573 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001574 }
fredc649fe492012-04-19 01:07:18 -07001575 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001576
fredc0f420372012-04-12 00:02:00 -07001577 case MESSAGE_DISABLE:
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001578 if (DBG) {
1579 Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
1580 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001581 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1582 if (mEnable && mBluetooth != null) {
1583 waitForOnOff(true, false);
1584 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001585 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001586 waitForOnOff(false, false);
1587 } else {
1588 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001589 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001590 }
fredc0f420372012-04-12 00:02:00 -07001591 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001592
Stanley Tng873b5702017-05-01 21:27:31 -07001593 case MESSAGE_RESTORE_USER_SETTING:
Jack He8caab152018-03-02 13:08:36 -08001594 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1595 if (DBG) {
1596 Slog.d(TAG, "Restore Bluetooth state to disabled");
Stanley Tng873b5702017-05-01 21:27:31 -07001597 }
Jack He8caab152018-03-02 13:08:36 -08001598 persistBluetoothSetting(BLUETOOTH_OFF);
1599 mEnableExternal = false;
1600 sendDisableMsg(
1601 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1602 mContext.getPackageName());
1603 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1604 if (DBG) {
1605 Slog.d(TAG, "Restore Bluetooth state to enabled");
1606 }
1607 mQuietEnableExternal = false;
1608 mEnableExternal = true;
1609 // waive WRITE_SECURE_SETTINGS permission check
1610 sendEnableMsg(false,
1611 BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING,
1612 mContext.getPackageName());
Stanley Tng873b5702017-05-01 21:27:31 -07001613 }
1614 break;
1615
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001616 case MESSAGE_REGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001617 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001618 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001619 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001620 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001621 case MESSAGE_UNREGISTER_ADAPTER: {
fredc0f420372012-04-12 00:02:00 -07001622 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001623 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001624 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001625 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001626 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: {
1627 IBluetoothStateChangeCallback callback =
1628 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001629 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001630 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001631 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001632 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: {
1633 IBluetoothStateChangeCallback callback =
1634 (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001635 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001636 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001637 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001638 case MESSAGE_ADD_PROXY_DELAYED: {
Jack He8caab152018-03-02 13:08:36 -08001639 ProfileServiceConnections psc = mProfileServices.get(msg.arg1);
Benjamin Franze8b98922014-11-12 15:57:54 +00001640 if (psc == null) {
1641 break;
1642 }
1643 IBluetoothProfileServiceConnection proxy =
1644 (IBluetoothProfileServiceConnection) msg.obj;
1645 psc.addProxy(proxy);
1646 break;
1647 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001648 case MESSAGE_BIND_PROFILE_SERVICE: {
Benjamin Franze8b98922014-11-12 15:57:54 +00001649 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1650 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1651 if (psc == null) {
1652 break;
1653 }
1654 psc.bindService();
1655 break;
1656 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001657 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
1658 if (DBG) {
1659 Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
1660 }
fredc0f420372012-04-12 00:02:00 -07001661
1662 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001663 try {
1664 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001665 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001666 mBluetoothGatt =
1667 IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
Myles Watson304ebf22018-05-11 08:47:24 -07001668 continueFromBleOnState();
Matthew Xieddf7e472013-03-01 18:41:02 -08001669 break;
1670 } // else must be SERVICE_IBLUETOOTH
1671
1672 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001673 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001674
fredc0f420372012-04-12 00:02:00 -07001675 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001676 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001677 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001678
Ajay Panicker4bb48302016-03-31 14:14:27 -07001679 if (!isNameAndAddressSet()) {
1680 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1681 mHandler.sendMessage(getMsg);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001682 if (mGetNameAddressOnly) {
1683 return;
1684 }
Ajay Panicker4bb48302016-03-31 14:14:27 -07001685 }
1686
Matthew Xiecdce0b92012-07-12 19:06:15 -07001687 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001688 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001689 mBluetooth.registerCallback(mBluetoothCallback);
1690 } catch (RemoteException re) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001691 Slog.e(TAG, "Unable to register BluetoothCallback", re);
fredcbf072a72012-05-09 16:52:50 -07001692 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001693 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001694 sendBluetoothServiceUpCallback();
1695
Matthew Xiecdce0b92012-07-12 19:06:15 -07001696 //Do enable request
1697 try {
Jack Hea6e031c2017-12-08 12:21:37 -08001698 if (!mQuietEnable) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001699 if (!mBluetooth.enable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001700 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001701 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001702 } else {
1703 if (!mBluetooth.enableNoAutoConnect()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001704 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001705 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001706 }
1707 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001708 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001709 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001710 } finally {
1711 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001712 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001713
1714 if (!mEnable) {
1715 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001716 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001717 waitForOnOff(false, false);
1718 }
fredc649fe492012-04-19 01:07:18 -07001719 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001720 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001721 case MESSAGE_BLUETOOTH_STATE_CHANGE: {
fredcbf072a72012-05-09 16:52:50 -07001722 int prevState = msg.arg1;
1723 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001724 if (DBG) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001725 Slog.d(TAG,
1726 "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(
1727 prevState) + " > " + BluetoothAdapter.nameForState(
1728 newState));
Marie Janssencb21ad72016-12-13 10:51:02 -08001729 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001730 mState = newState;
1731 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001732 // handle error state transition case from TURNING_ON to OFF
1733 // unbind and rebind bluetooth service and enable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001734 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && (newState
1735 == BluetoothAdapter.STATE_OFF) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001736 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001737 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001738 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && (newState
1739 == BluetoothAdapter.STATE_BLE_ON) && (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001740 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001741 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001742 // If we tried to enable BT while BT was in the process of shutting down,
1743 // wait for the BT process to fully tear down and then force a restart
1744 // here. This is a bit of a hack (b/29363429).
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001745 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && (newState
1746 == BluetoothAdapter.STATE_OFF)) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001747 if (mEnable) {
1748 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1749 waitForOnOff(false, true);
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001750 Message restartMsg =
1751 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Calvin Ona0b91d72016-06-15 17:58:23 -07001752 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1753 }
1754 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001755 if (newState == BluetoothAdapter.STATE_ON
1756 || newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001757 // bluetooth is working, reset the counter
1758 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001759 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001760 mErrorRecoveryRetryCounter = 0;
1761 }
1762 }
fredc649fe492012-04-19 01:07:18 -07001763 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001764 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001765 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001766 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001767 try {
1768 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001769 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1770 // if service is unbinded already, do nothing and return
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001771 if (mBluetooth == null) {
1772 break;
1773 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001774 mBluetooth = null;
1775 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1776 mBluetoothGatt = null;
1777 break;
1778 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001779 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001780 break;
1781 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001782 } finally {
1783 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301784 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001785
Marie Janssene54b4222017-03-16 18:10:59 -07001786 // log the unexpected crash
1787 addCrashLog();
Jack He8caab152018-03-02 13:08:36 -08001788 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH,
1789 mContext.getPackageName(), false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001790 if (mEnable) {
1791 mEnable = false;
1792 // Send a Bluetooth Restart message
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001793 Message restartMsg =
1794 mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1795 mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
Zhihai Xu40874a02012-10-08 17:57:03 -07001796 }
1797
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001798 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001799
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001800 // Send BT state broadcast to update
1801 // the BT icon correctly
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001802 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || (mState
1803 == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001804 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001805 BluetoothAdapter.STATE_TURNING_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001806 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001807 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001808 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1809 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001810 BluetoothAdapter.STATE_OFF);
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001811 }
1812
1813 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1814 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001815 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001816 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001817 case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
Marie Janssencb21ad72016-12-13 10:51:02 -08001818 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301819 /* Enable without persisting the setting as
1820 it doesnt change when IBluetooth
1821 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001822 mEnable = true;
Jack He8caab152018-03-02 13:08:36 -08001823 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
1824 mContext.getPackageName(), true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001825 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301826 break;
1827 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001828 case MESSAGE_TIMEOUT_BIND: {
1829 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1830 mBluetoothLock.writeLock().lock();
1831 mBinding = false;
1832 mBluetoothLock.writeLock().unlock();
1833 break;
1834 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001835 case MESSAGE_TIMEOUT_UNBIND: {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001836 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001837 mBluetoothLock.writeLock().lock();
1838 mUnbinding = false;
1839 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001840 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001841 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001842
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001843 case MESSAGE_USER_SWITCHED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001844 if (DBG) {
1845 Slog.d(TAG, "MESSAGE_USER_SWITCHED");
1846 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001847 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001848
Zhihai Xu40874a02012-10-08 17:57:03 -07001849 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001850 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001851 try {
1852 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001853 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001854 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001855 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001856 } catch (RemoteException re) {
1857 Slog.e(TAG, "Unable to unregister", re);
1858 } finally {
1859 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001860 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001861
1862 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1863 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1864 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1865 mState = BluetoothAdapter.STATE_OFF;
1866 }
1867 if (mState == BluetoothAdapter.STATE_OFF) {
1868 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1869 mState = BluetoothAdapter.STATE_TURNING_ON;
1870 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001871
1872 waitForOnOff(true, false);
1873
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001874 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1875 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1876 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001877
Benjamin Franze8b98922014-11-12 15:57:54 +00001878 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001879 // disable
Jack He8caab152018-03-02 13:08:36 -08001880 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1881 mContext.getPackageName(), false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001882 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001883 // Pbap service need receive STATE_TURNING_OFF intent to close
1884 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001885 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001886
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001887 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001888
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001889 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001890 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001891 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001892
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001893 try {
1894 mBluetoothLock.writeLock().lock();
1895 if (mBluetooth != null) {
1896 mBluetooth = null;
1897 // Unbind
1898 mContext.unbindService(mConnection);
1899 }
1900 mBluetoothGatt = null;
1901 } finally {
1902 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001903 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001904
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001905 //
1906 // If disabling Bluetooth times out, wait for an
1907 // additional amount of time to ensure the process is
1908 // shut down completely before attempting to restart.
1909 //
1910 if (didDisableTimeout) {
1911 SystemClock.sleep(3000);
1912 } else {
1913 SystemClock.sleep(100);
1914 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001915
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001916 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1917 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001918 // enable
Jack He8caab152018-03-02 13:08:36 -08001919 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH,
1920 mContext.getPackageName(), true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001921 // mEnable flag could have been reset on disableBLE. Reenable it.
1922 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001923 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001924 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001925 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1926 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001927 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001928 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1929 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001930 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001931 }
John Spurlock8a985d22014-02-25 09:40:05 -05001932 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001933 break;
1934 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001935 case MESSAGE_USER_UNLOCKED: {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001936 if (DBG) {
1937 Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1938 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001939 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1940
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001941 if (mEnable && !mBinding && (mBluetooth == null)) {
1942 // We should be connected, but we gave up for some
1943 // reason; maybe the Bluetooth service wasn't encryption
1944 // aware, so try binding again.
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001945 if (DBG) {
1946 Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1947 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001948 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001949 }
1950 }
fredc0f420372012-04-12 00:02:00 -07001951 }
1952 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001953 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001954
Zhihai Xu401202b2012-12-03 11:36:21 -08001955 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001956 mQuietEnable = quietMode;
1957
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001958 try {
1959 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001960 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001961 //Start bind timeout and bind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001962 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1963 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001964 Intent i = new Intent(IBluetooth.class.getName());
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001965 if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001966 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001967 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001968 } else {
1969 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001970 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001971 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001972 //Enable bluetooth
1973 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001974 if (!mQuietEnable) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001975 if (!mBluetooth.enable()) {
1976 Slog.e(TAG, "IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001977 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001978 } else {
1979 if (!mBluetooth.enableNoAutoConnect()) {
1980 Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001981 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001982 }
1983 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08001984 Slog.e(TAG, "Unable to call enable()", e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001985 }
1986 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001987 } finally {
1988 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001989 }
1990 }
1991
Dianne Hackborn221ea892013-08-04 16:50:16 -07001992 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1993 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1994 intent.setComponent(comp);
1995 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001996 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001997 return false;
1998 }
1999 return true;
2000 }
2001
Zhihai Xu401202b2012-12-03 11:36:21 -08002002 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002003 try {
2004 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08002005 if (mBluetooth != null) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002006 if (DBG) {
2007 Slog.d(TAG, "Sending off request.");
2008 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002009 if (!mBluetooth.disable()) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002010 Slog.e(TAG, "IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07002011 }
2012 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002013 } catch (RemoteException e) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002014 Slog.e(TAG, "Unable to call disable()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002015 } finally {
2016 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07002017 }
2018 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002019
2020 private boolean checkIfCallerIsForegroundUser() {
2021 int foregroundUser;
2022 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002023 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07002024 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00002025 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
2026 UserInfo ui = um.getProfileParent(callingUser);
2027 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08002028 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07002029 boolean valid = false;
2030 try {
2031 foregroundUser = ActivityManager.getCurrentUser();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002032 valid = (callingUser == foregroundUser) || parentUser == foregroundUser
2033 || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08002034 if (DBG && !valid) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002035 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser="
2036 + callingUser + " parentUser=" + parentUser + " foregroundUser="
2037 + foregroundUser);
Zhihai Xu40874a02012-10-08 17:57:03 -07002038 }
2039 } finally {
2040 Binder.restoreCallingIdentity(callingIdentity);
2041 }
2042 return valid;
2043 }
2044
Nitin Arorad055adb2015-03-02 15:03:51 -08002045 private void sendBleStateChanged(int prevState, int newState) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002046 if (DBG) {
2047 Slog.d(TAG,
2048 "Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
2049 + BluetoothAdapter.nameForState(newState));
2050 }
Nitin Arorad055adb2015-03-02 15:03:51 -08002051 // Send broadcast message to everyone else
2052 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
2053 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2054 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2055 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2056 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
2057 }
2058
Zhihai Xu40874a02012-10-08 17:57:03 -07002059 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08002060 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08002061 if (prevState == newState) { // No change. Nothing to do.
2062 return;
2063 }
2064 // Notify all proxy objects first of adapter state change
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002065 if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002066 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002067 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07002068
Marie Janssencb21ad72016-12-13 10:51:02 -08002069 if (newState == BluetoothAdapter.STATE_OFF) {
2070 // If Bluetooth is off, send service down event to proxy objects, and unbind
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002071 if (DBG) {
2072 Slog.d(TAG, "Bluetooth is complete send Service Down");
2073 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002074 sendBluetoothServiceDownCallback();
2075 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08002076 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08002077 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08002078 isStandardBroadcast = false;
2079
Marie Janssencb21ad72016-12-13 10:51:02 -08002080 } else if (!intermediate_off) {
2081 // connect to GattService
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002082 if (DBG) {
2083 Slog.d(TAG, "Bluetooth is in LE only mode");
2084 }
Myles Watson304ebf22018-05-11 08:47:24 -07002085 if (mBluetoothGatt != null || !mContext.getPackageManager()
2086 .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
2087 continueFromBleOnState();
Marie Janssencb21ad72016-12-13 10:51:02 -08002088 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002089 if (DBG) {
2090 Slog.d(TAG, "Binding Bluetooth GATT service");
2091 }
Myles Watson304ebf22018-05-11 08:47:24 -07002092 Intent i = new Intent(IBluetoothGatt.class.getName());
2093 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
2094 UserHandle.CURRENT);
Nitin Arorad055adb2015-03-02 15:03:51 -08002095 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002096 sendBleStateChanged(prevState, newState);
2097 //Don't broadcase this as std intent
2098 isStandardBroadcast = false;
2099
2100 } else if (intermediate_off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002101 if (DBG) {
2102 Slog.d(TAG, "Intermediate off, back to LE only mode");
2103 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002104 // For LE only mode, broadcast as is
2105 sendBleStateChanged(prevState, newState);
2106 sendBluetoothStateCallback(false); // BT is OFF for general users
2107 // Broadcast as STATE_OFF
2108 newState = BluetoothAdapter.STATE_OFF;
2109 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08002110 }
Marie Janssencb21ad72016-12-13 10:51:02 -08002111 } else if (newState == BluetoothAdapter.STATE_ON) {
2112 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
2113 sendBluetoothStateCallback(isUp);
2114 sendBleStateChanged(prevState, newState);
2115
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002116 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON
2117 || newState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002118 sendBleStateChanged(prevState, newState);
2119 isStandardBroadcast = false;
2120
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002121 } else if (newState == BluetoothAdapter.STATE_TURNING_ON
2122 || newState == BluetoothAdapter.STATE_TURNING_OFF) {
Marie Janssencb21ad72016-12-13 10:51:02 -08002123 sendBleStateChanged(prevState, newState);
2124 }
2125
2126 if (isStandardBroadcast) {
2127 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
2128 // Show prevState of BLE_ON as OFF to standard users
2129 prevState = BluetoothAdapter.STATE_OFF;
2130 }
2131 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
2132 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
2133 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
2134 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2135 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07002136 }
2137 }
2138
2139 /**
2140 * if on is true, wait for state become ON
2141 * if off is true, wait for state become OFF
2142 * if both on and off are false, wait for state not ON
2143 */
2144 private boolean waitForOnOff(boolean on, boolean off) {
2145 int i = 0;
2146 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002147 try {
2148 mBluetoothLock.readLock().lock();
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002149 if (mBluetooth == null) {
2150 break;
2151 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002152 if (on) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002153 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
2154 return true;
2155 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002156 } else if (off) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002157 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
2158 return true;
2159 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002160 } else {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002161 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
2162 return true;
2163 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002164 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002165 } catch (RemoteException e) {
2166 Slog.e(TAG, "getState()", e);
2167 break;
2168 } finally {
2169 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002170 }
2171 if (on || off) {
2172 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002173 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002174 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002175 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002176 i++;
2177 }
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002178 Slog.e(TAG, "waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002179 return false;
2180 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002181
Jack He8caab152018-03-02 13:08:36 -08002182 private void sendDisableMsg(int reason, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002183 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Jack He8caab152018-03-02 13:08:36 -08002184 addActiveLog(reason, packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002185 }
2186
Jack He8caab152018-03-02 13:08:36 -08002187 private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002188 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0));
Jack He8caab152018-03-02 13:08:36 -08002189 addActiveLog(reason, packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002190 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002191 }
2192
Jack He8caab152018-03-02 13:08:36 -08002193 private void addActiveLog(int reason, String packageName, boolean enable) {
Marie Janssen59804562016-12-28 14:13:21 -08002194 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002195 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002196 mActiveLogs.remove();
2197 }
Jack He8caab152018-03-02 13:08:36 -08002198 mActiveLogs.add(
2199 new ActiveLog(reason, packageName, enable, System.currentTimeMillis()));
Marie Janssen59804562016-12-28 14:13:21 -08002200 }
Tej Singhd8e7cc62018-03-22 18:30:31 +00002201
2202 int state = enable ? StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED :
2203 StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED;
2204 StatsLog.write_non_chained(StatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
2205 Binder.getCallingUid(), null, state, reason, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -08002206 }
2207
Marie Janssene54b4222017-03-16 18:10:59 -07002208 private void addCrashLog() {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002209 synchronized (mCrashTimestamps) {
2210 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) {
2211 mCrashTimestamps.removeFirst();
2212 }
2213 mCrashTimestamps.add(System.currentTimeMillis());
2214 mCrashes++;
2215 }
Marie Janssene54b4222017-03-16 18:10:59 -07002216 }
2217
Marie Janssen2977c3e2016-11-09 12:01:24 -08002218 private void recoverBluetoothServiceFromError(boolean clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002219 Slog.e(TAG, "recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002220 try {
2221 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002222 if (mBluetooth != null) {
2223 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002224 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002225 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002226 } catch (RemoteException re) {
2227 Slog.e(TAG, "Unable to unregister", re);
2228 } finally {
2229 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002230 }
2231
2232 SystemClock.sleep(500);
2233
2234 // disable
Jack He8caab152018-03-02 13:08:36 -08002235 addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR,
2236 mContext.getPackageName(), false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002237 handleDisable();
2238
2239 waitForOnOff(false, true);
2240
2241 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002242
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002243 try {
2244 mBluetoothLock.writeLock().lock();
2245 if (mBluetooth != null) {
2246 mBluetooth = null;
2247 // Unbind
2248 mContext.unbindService(mConnection);
2249 }
2250 mBluetoothGatt = null;
2251 } finally {
2252 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002253 }
2254
2255 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2256 mState = BluetoothAdapter.STATE_OFF;
2257
Marie Janssen2977c3e2016-11-09 12:01:24 -08002258 if (clearBle) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002259 clearBleApps();
Marie Janssen2977c3e2016-11-09 12:01:24 -08002260 }
2261
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002262 mEnable = false;
2263
2264 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2265 // Send a Bluetooth Restart message to reenable bluetooth
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002266 Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002267 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2268 } else {
2269 // todo: notify user to power down and power up phone to make bluetooth work.
2270 }
2271 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002272
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002273 private boolean isBluetoothDisallowed() {
2274 long callingIdentity = Binder.clearCallingIdentity();
2275 try {
2276 return mContext.getSystemService(UserManager.class)
2277 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2278 } finally {
2279 Binder.restoreCallingIdentity(callingIdentity);
2280 }
2281 }
2282
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002283 /**
2284 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002285 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2286 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002287 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002288 * @param userId user to disable bluetooth sharing for.
2289 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002290 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002291 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002292 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2293 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002294 final int newState =
2295 bluetoothSharingDisallowed ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2296 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002297 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002298 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002299 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2300 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002301 } catch (Exception e) {
2302 // The component was not found, do nothing.
2303 }
2304 }
2305
Mike Lockwood726d4de2014-10-28 14:06:28 -07002306 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002307 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002308 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
2309 return;
2310 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002311 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002312
2313 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2314
2315 if (!protoOut) {
2316 writer.println("Bluetooth Status");
2317 writer.println(" enabled: " + isEnabled());
2318 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2319 writer.println(" address: " + mAddress);
2320 writer.println(" name: " + mName);
2321 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002322 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002323 String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
2324 (int) (onDuration / (1000 * 60 * 60)),
2325 (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
2326 (int) (onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002327 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002328 }
2329
Marie Janssena95924d2017-01-18 09:37:52 -08002330 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002331 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002332 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002333 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002334 for (ActiveLog log : mActiveLogs) {
2335 writer.println(" " + log);
2336 }
Marie Janssen59804562016-12-28 14:13:21 -08002337 }
2338
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002339 writer.println(
2340 "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2341 if (mCrashes == CRASH_LOG_MAX_SIZE) {
2342 writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2343 }
Marie Janssene54b4222017-03-16 18:10:59 -07002344 for (Long time : mCrashTimestamps) {
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002345 writer.println(" " + timeToLog(time));
Marie Janssene54b4222017-03-16 18:10:59 -07002346 }
2347
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002348 writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
2349 + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002350 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002351 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002352 }
2353
Marie Janssena95924d2017-01-18 09:37:52 -08002354 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002355 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002356 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002357 // Add arg to produce output
2358 args = new String[1];
2359 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002360 }
Marie Janssen59804562016-12-28 14:13:21 -08002361 }
2362
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002363 if (mBluetoothBinder == null) {
2364 errorMsg = "Bluetooth Service not connected";
2365 } else {
2366 try {
2367 mBluetoothBinder.dump(fd, args);
2368 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002369 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002370 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002371 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002372 if (errorMsg != null) {
2373 // Silently return if we are extracting metrics in Protobuf format
Myles Watsonb5cd11a2017-11-27 16:42:11 -08002374 if (protoOut) {
2375 return;
2376 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002377 writer.println(errorMsg);
2378 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002379 }
Jack He8caab152018-03-02 13:08:36 -08002380
2381 private static String getEnableDisableReasonString(int reason) {
2382 switch (reason) {
2383 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
2384 return "APPLICATION_REQUEST";
2385 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE:
2386 return "AIRPLANE_MODE";
2387 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_DISALLOWED:
2388 return "DISALLOWED";
2389 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED:
2390 return "RESTARTED";
2391 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_START_ERROR:
2392 return "START_ERROR";
2393 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT:
2394 return "SYSTEM_BOOT";
2395 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_CRASH:
2396 return "CRASH";
2397 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH:
2398 return "USER_SWITCH";
2399 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
2400 return "RESTORE_USER_SETTING";
2401 case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
2402 default: return "UNKNOWN[" + reason + "]";
2403 }
2404 }
fredc0f420372012-04-12 00:02:00 -07002405}