blob: 75206e48aa8b896f2bfa317443ce5b8325c44c1f [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;
fredc0f420372012-04-12 00:02:00 -070024import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070025import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070026import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000027import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070028import android.bluetooth.IBluetoothManager;
29import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000030import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070031import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070032import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070033import android.content.BroadcastReceiver;
34import android.content.ComponentName;
35import android.content.ContentResolver;
36import android.content.Context;
37import android.content.Intent;
38import android.content.IntentFilter;
39import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070040import android.content.pm.ApplicationInfo;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010041import android.content.pm.IPackageManager;
Matthew Xie32ab77b2013-05-08 19:26:57 -070042import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000043import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070044import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070045import android.os.Binder;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010046import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070047import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070048import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070049import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070050import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070051import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070052import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070053import android.os.RemoteException;
Zhihai Xu40874a02012-10-08 17:57:03 -070054import android.os.SystemClock;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070055import android.os.UserHandle;
Benjamin Franze8b98922014-11-12 15:57:54 +000056import android.os.UserManager;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010057import android.os.UserManagerInternal;
58import android.os.UserManagerInternal.UserRestrictionsListener;
fredc0f420372012-04-12 00:02:00 -070059import android.provider.Settings;
Wei Wang67d84162015-04-26 17:04:29 -070060import android.provider.Settings.SettingNotFoundException;
Jeff Sharkey67609c72016-03-05 14:29:13 -070061import android.util.Slog;
Mike Lockwood726d4de2014-10-28 14:06:28 -070062
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060063import com.android.internal.util.DumpUtils;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010064import com.android.server.pm.UserRestrictionsUtils;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010065
Mike Lockwood726d4de2014-10-28 14:06:28 -070066import java.io.FileDescriptor;
67import java.io.PrintWriter;
Benjamin Franze8b98922014-11-12 15:57:54 +000068import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080069import java.util.LinkedList;
Benjamin Franze8b98922014-11-12 15:57:54 +000070import java.util.Map;
Pavel Grafov4f4f6f82017-03-28 13:44:04 +010071import java.util.concurrent.ConcurrentHashMap;
72import java.util.concurrent.locks.ReentrantReadWriteLock;
Miao Chou658bf2f2015-06-26 17:14:35 -070073
Marie Janssen59804562016-12-28 14:13:21 -080074
fredc0f420372012-04-12 00:02:00 -070075class BluetoothManagerService extends IBluetoothManager.Stub {
76 private static final String TAG = "BluetoothManagerService";
Pavlin Radoslavov41401112016-06-27 15:25:18 -070077 private static final boolean DBG = true;
fredc0f420372012-04-12 00:02:00 -070078
fredc0f420372012-04-12 00:02:00 -070079 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
80 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
Marie Janssene54b4222017-03-16 18:10:59 -070081
Zhihai Xud31c3222012-10-31 16:08:57 -070082 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID="bluetooth_addr_valid";
fredc0f420372012-04-12 00:02:00 -070083 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address";
84 private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name";
Marie Janssene54b4222017-03-16 18:10:59 -070085
86 private static final int ACTIVE_LOG_MAX_SIZE = 20;
87 private static final int CRASH_LOG_MAX_SIZE = 100;
Ajay Panicker467bc042017-02-22 12:23:15 -080088 private static final String REASON_AIRPLANE_MODE = "airplane mode";
Myles Watson6291fae2017-06-29 03:12:02 -070089 private static final String REASON_DISALLOWED = "disallowed by system";
90 private static final String REASON_SHARING_DISALLOWED = "sharing disallowed by system";
Marie Janssene54b4222017-03-16 18:10:59 -070091 private static final String REASON_RESTARTED = "automatic restart";
92 private static final String REASON_START_CRASH = "turn-on crash";
Ajay Panicker467bc042017-02-22 12:23:15 -080093 private static final String REASON_SYSTEM_BOOT = "system boot";
Marie Janssene54b4222017-03-16 18:10:59 -070094 private static final String REASON_UNEXPECTED = "unexpected crash";
95 private static final String REASON_USER_SWITCH = "user switch";
Stanley Tng873b5702017-05-01 21:27:31 -070096 private static final String REASON_RESTORE_USER_SETTING = "restore user setting";
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
133 private static final int BLUETOOTH_OFF=0;
134 // Bluetooth persisted setting is on
135 // and Airplane mode won't affect Bluetooth state at start up
136 private static final int BLUETOOTH_ON_BLUETOOTH=1;
137 // Bluetooth persisted setting is on
138 // but Airplane mode will affect Bluetooth state at start up
139 // and Airplane mode will have higher priority.
140 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;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700157 private final ReentrantReadWriteLock mBluetoothLock =
158 new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700159 private boolean mBinding;
160 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800161
Zhihai Xu401202b2012-12-03 11:36:21 -0800162 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700163 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800164 private boolean mEnable;
165
Marie Janssene54b4222017-03-16 18:10:59 -0700166 private CharSequence timeToLog(long timestamp) {
167 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
168 }
169
Marie Janssen59804562016-12-28 14:13:21 -0800170 /**
171 * Used for tracking apps that enabled / disabled Bluetooth.
172 */
173 private class ActiveLog {
174 private String mPackageName;
175 private boolean mEnable;
176 private long mTimestamp;
177
178 public ActiveLog(String packageName, boolean enable, long timestamp) {
179 mPackageName = packageName;
180 mEnable = enable;
181 mTimestamp = timestamp;
182 }
183
184 public long getTime() {
185 return mTimestamp;
186 }
187
188 public String toString() {
Marie Janssene54b4222017-03-16 18:10:59 -0700189 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ") + " by "
190 + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800191 }
192
193 }
194
195 private LinkedList<ActiveLog> mActiveLogs;
Marie Janssene54b4222017-03-16 18:10:59 -0700196 private LinkedList<Long> mCrashTimestamps;
197 private int mCrashes;
Marie Janssen59804562016-12-28 14:13:21 -0800198
199 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800200 // synchronize with broadcast receiver.
201 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800202 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800203
204 // Map of apps registered to keep BLE scanning on.
205 private Map<IBinder, ClientDeathRecipient> mBleApps = new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
206
Zhihai Xu40874a02012-10-08 17:57:03 -0700207 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700208 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800209 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200210 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700211
Benjamin Franze8b98922014-11-12 15:57:54 +0000212 // Save a ProfileServiceConnections object for each of the bound
213 // bluetooth profile services
214 private final Map <Integer, ProfileServiceConnections> mProfileServices =
215 new HashMap <Integer, ProfileServiceConnections>();
216
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700217 private final boolean mPermissionReviewRequired;
218
Marie Janssen59804562016-12-28 14:13:21 -0800219 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700220 @Override
221 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
222 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
223 mHandler.sendMessage(msg);
224 }
225 };
226
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100227 private final UserRestrictionsListener mUserRestrictionsListener =
228 new UserRestrictionsListener() {
229 @Override
230 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
231 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700232
233 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
234 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
235 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
236 UserManager.DISALLOW_BLUETOOTH_SHARING));
Lenka Trochtovac6f0e232017-01-17 10:35:49 +0100237 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100238
Myles Watson6291fae2017-06-29 03:12:02 -0700239 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
240 if (userId == UserHandle.USER_SYSTEM &&
241 UserRestrictionsUtils.restrictionsChanged(
242 prevRestrictions, newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
243 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
244 UserManager.DISALLOW_BLUETOOTH)) {
245 updateOppLauncherComponentState(userId, true); // Sharing disallowed
246 sendDisableMsg(REASON_DISALLOWED);
247 } else {
248 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
249 UserManager.DISALLOW_BLUETOOTH_SHARING));
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100250 }
251 }
252 }
253 };
254
Ajay Panicker467bc042017-02-22 12:23:15 -0800255 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
256 @Override
257 public void onChange(boolean unused) {
258 synchronized(this) {
259 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
280 Slog.d(TAG, "Airplane Mode change - current state: " +
281 BluetoothAdapter.nameForState(st));
282
283 if (isAirplaneModeOn()) {
284 // Clear registered LE apps to force shut-off
285 clearBleApps();
286
287 // If state is BLE_ON make sure we trigger disableBLE
288 if (st == BluetoothAdapter.STATE_BLE_ON) {
289 try {
290 mBluetoothLock.readLock().lock();
291 if (mBluetooth != null) {
292 mBluetooth.onBrEdrDown();
293 mEnable = false;
294 mEnableExternal = false;
295 }
296 } catch (RemoteException e) {
297 Slog.e(TAG,"Unable to call onBrEdrDown", e);
298 } finally {
299 mBluetoothLock.readLock().unlock();
300 }
301 } else if (st == BluetoothAdapter.STATE_ON){
302 sendDisableMsg(REASON_AIRPLANE_MODE);
303 }
304 } else if (mEnableExternal) {
305 sendEnableMsg(mQuietEnableExternal, REASON_AIRPLANE_MODE);
306 }
307 }
308 }
309 };
310
fredcbf072a72012-05-09 16:52:50 -0700311 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700312 @Override
313 public void onReceive(Context context, Intent intent) {
314 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700315 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700316 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700317 if (DBG) Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
fredc0f420372012-04-12 00:02:00 -0700318 if (newName != null) {
319 storeNameAndAddress(newName, null);
320 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700321 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
322 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
323 if (newAddress != null) {
324 if (DBG) Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
325 storeNameAndAddress(null, newAddress);
326 } else {
327 if (DBG) Slog.e(TAG, "No Bluetooth Adapter address parameter found");
328 }
Stanley Tng873b5702017-05-01 21:27:31 -0700329 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
330 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
331 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
332 // The Bluetooth On state may be changed during system restore.
333 final String prevValue = intent.getStringExtra(
334 Intent.EXTRA_SETTING_PREVIOUS_VALUE);
335 final String newValue = intent.getStringExtra(
336 Intent.EXTRA_SETTING_NEW_VALUE);
337
338 if (DBG) Slog.d(TAG, "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" +
339 prevValue + ", newValue=" + newValue);
340
341 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
342 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
343 newValue.equals("0") ?
344 RESTORE_SETTING_TO_OFF :
345 RESTORE_SETTING_TO_ON, 0);
346 mHandler.sendMessage(msg);
347 }
348 }
fredc0f420372012-04-12 00:02:00 -0700349 }
350 }
351 };
352
353 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700354 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700355
fredc0f420372012-04-12 00:02:00 -0700356 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700357
Svet Ganov77df6f32016-08-17 11:46:34 -0700358 mPermissionReviewRequired = context.getResources().getBoolean(
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700359 com.android.internal.R.bool.config_permissionReviewRequired);
360
Marie Janssen59804562016-12-28 14:13:21 -0800361 mActiveLogs = new LinkedList<ActiveLog>();
Marie Janssene54b4222017-03-16 18:10:59 -0700362 mCrashTimestamps = new LinkedList<Long>();
363 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700364 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800365 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800366 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700367 mBinding = false;
368 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700369 mEnable = false;
370 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800371 mQuietEnableExternal = false;
372 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700373 mAddress = null;
374 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800375 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700376 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700377 // Observe BLE scan only mode settings change.
378 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700379 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
380 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700381
382 IntentFilter filter = new IntentFilter();
383 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
384 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
385 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700386 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700387 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700388
fredc0f420372012-04-12 00:02:00 -0700389 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800390 if (isBluetoothPersistedStateOn()) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700391 if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
Zhihai Xu401202b2012-12-03 11:36:21 -0800392 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700393 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200394
Ajay Panicker467bc042017-02-22 12:23:15 -0800395 String airplaneModeRadios = Settings.Global.getString(mContentResolver,
396 Settings.Global.AIRPLANE_MODE_RADIOS);
397 if (airplaneModeRadios == null ||
398 airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
399 mContentResolver.registerContentObserver(
400 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
401 true, mAirplaneModeObserver);
402 }
403
Marie Janssen59804562016-12-28 14:13:21 -0800404 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200405 try {
Marie Janssen59804562016-12-28 14:13:21 -0800406 systemUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui",
Jeff Sharkeyc5967e92016-01-07 18:50:29 -0700407 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200408 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700409 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700410 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200411 }
Marie Janssen59804562016-12-28 14:13:21 -0800412 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700413 }
414
fredc649fe492012-04-19 01:07:18 -0700415 /**
416 * Returns true if airplane mode is currently on
417 */
418 private final boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700419 return Settings.Global.getInt(mContext.getContentResolver(),
420 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700421 }
422
423 /**
424 * Returns true if the Bluetooth saved state is "on"
425 */
426 private final boolean isBluetoothPersistedStateOn() {
Marie Janssen9fa24912016-10-18 10:04:24 -0700427 int state = Settings.Global.getInt(mContentResolver,
428 Settings.Global.BLUETOOTH_ON, -1);
429 if (DBG) Slog.d(TAG, "Bluetooth persisted state: " + state);
430 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800431 }
432
433 /**
434 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
435 */
436 private final boolean isBluetoothPersistedStateOnBluetooth() {
437 return Settings.Global.getInt(mContentResolver,
Andre Eisenbach8c184312016-09-06 18:03:10 -0700438 Settings.Global.BLUETOOTH_ON, BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700439 }
440
441 /**
442 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700443 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800444 private void persistBluetoothSetting(int value) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700445 if (DBG) Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
Marie Janssenfa630682016-12-15 13:51:30 -0800446 // waive WRITE_SECURE_SETTINGS permission check
447 long callingIdentity = Binder.clearCallingIdentity();
Jeff Brownbf6f6f92012-09-25 15:03:20 -0700448 Settings.Global.putInt(mContext.getContentResolver(),
449 Settings.Global.BLUETOOTH_ON,
Zhihai Xu401202b2012-12-03 11:36:21 -0800450 value);
Marie Janssenfa630682016-12-15 13:51:30 -0800451 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700452 }
453
454 /**
455 * Returns true if the Bluetooth Adapter's name and address is
456 * locally cached
457 * @return
458 */
fredc0f420372012-04-12 00:02:00 -0700459 private boolean isNameAndAddressSet() {
460 return mName !=null && mAddress!= null && mName.length()>0 && mAddress.length()>0;
461 }
462
fredc649fe492012-04-19 01:07:18 -0700463 /**
464 * Retrieve the Bluetooth Adapter's name and address and save it in
465 * in the local cache
466 */
fredc0f420372012-04-12 00:02:00 -0700467 private void loadStoredNameAndAddress() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700468 if (DBG) Slog.d(TAG, "Loading stored name and address");
Zhihai Xud31c3222012-10-31 16:08:57 -0700469 if (mContext.getResources().getBoolean
470 (com.android.internal.R.bool.config_bluetooth_address_validation) &&
471 Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0) == 0) {
472 // if the valid flag is not set, don't load the address and name
Jeff Sharkey67609c72016-03-05 14:29:13 -0700473 if (DBG) Slog.d(TAG, "invalid bluetooth name and address stored");
Zhihai Xud31c3222012-10-31 16:08:57 -0700474 return;
475 }
fredc0f420372012-04-12 00:02:00 -0700476 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
477 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700478 if (DBG) Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
fredc0f420372012-04-12 00:02:00 -0700479 }
480
fredc649fe492012-04-19 01:07:18 -0700481 /**
482 * Save the Bluetooth name and address in the persistent store.
483 * Only non-null values will be saved.
484 * @param name
485 * @param address
486 */
fredc0f420372012-04-12 00:02:00 -0700487 private void storeNameAndAddress(String name, String address) {
488 if (name != null) {
489 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700490 mName = name;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700491 if (DBG) Slog.d(TAG,"Stored Bluetooth name: " +
fredc649fe492012-04-19 01:07:18 -0700492 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_NAME));
fredc0f420372012-04-12 00:02:00 -0700493 }
494
495 if (address != null) {
496 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
fredc0f420372012-04-12 00:02:00 -0700497 mAddress=address;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700498 if (DBG) Slog.d(TAG,"Stored Bluetoothaddress: " +
fredc649fe492012-04-19 01:07:18 -0700499 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS));
fredc0f420372012-04-12 00:02:00 -0700500 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700501
502 if ((name != null) && (address != null)) {
503 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
504 }
fredc0f420372012-04-12 00:02:00 -0700505 }
506
507 public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700508 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700509 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700510 return null;
511 }
fredc0f420372012-04-12 00:02:00 -0700512 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
513 msg.obj = callback;
514 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700515
516 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700517 }
518
519 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700520 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700521 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700522 return;
523 }
fredc0f420372012-04-12 00:02:00 -0700524 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
525 "Need BLUETOOTH permission");
526 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
527 msg.obj = callback;
528 mHandler.sendMessage(msg);
529 }
530
531 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
532 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
533 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800534 if (callback == null) {
535 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
536 return;
537 }
fredc0f420372012-04-12 00:02:00 -0700538 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
539 msg.obj = callback;
540 mHandler.sendMessage(msg);
541 }
542
543 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
544 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
545 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800546 if (callback == null) {
547 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
548 return;
549 }
fredc0f420372012-04-12 00:02:00 -0700550 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
551 msg.obj = callback;
552 mHandler.sendMessage(msg);
553 }
554
555 public boolean isEnabled() {
Zhihai Xu6eb76522012-11-29 15:41:04 -0800556 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
557 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700558 Slog.w(TAG,"isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700559 return false;
560 }
561
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700562 try {
563 mBluetoothLock.readLock().lock();
564 if (mBluetooth != null) return mBluetooth.isEnabled();
565 } catch (RemoteException e) {
566 Slog.e(TAG, "isEnabled()", e);
567 } finally {
568 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700569 }
570 return false;
571 }
572
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700573 public int getState() {
574 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
575 (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800576 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700577 return BluetoothAdapter.STATE_OFF;
578 }
579
580 try {
581 mBluetoothLock.readLock().lock();
582 if (mBluetooth != null) return mBluetooth.getState();
583 } catch (RemoteException e) {
584 Slog.e(TAG, "getState()", e);
585 } finally {
586 mBluetoothLock.readLock().unlock();
587 }
588 return BluetoothAdapter.STATE_OFF;
589 }
590
Nitin Arorad055adb2015-03-02 15:03:51 -0800591 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800592 private String mPackageName;
593
594 public ClientDeathRecipient(String packageName) {
595 mPackageName = packageName;
596 }
597
Nitin Arorad055adb2015-03-02 15:03:51 -0800598 public void binderDied() {
Marie Janssen59804562016-12-28 14:13:21 -0800599 if (DBG) Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800600 if (isBleAppPresent()) {
601 // Nothing to do, another app is here.
602 return;
603 }
604 if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
605 try {
606 mBluetoothLock.readLock().lock();
607 if (mBluetooth != null &&
608 mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
609 mEnable = false;
610 mBluetooth.onBrEdrDown();
Nitin Arorad055adb2015-03-02 15:03:51 -0800611 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800612 } catch (RemoteException e) {
613 Slog.e(TAG,"Unable to call onBrEdrDown", e);
614 } finally {
615 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800616 }
617 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800618
Marie Janssen59804562016-12-28 14:13:21 -0800619 public String getPackageName() {
620 return mPackageName;
621 }
622 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800623
Wei Wang67d84162015-04-26 17:04:29 -0700624 @Override
625 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700626 if (isAirplaneModeOn() && !mEnable) {
627 return false;
628 }
Wei Wang67d84162015-04-26 17:04:29 -0700629 try {
630 return (Settings.Global.getInt(mContentResolver,
631 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE)) != 0;
632 } catch (SettingNotFoundException e) {
633 }
634 return false;
635 }
636
Wei Wange4a744b2015-06-11 17:50:29 -0700637 // Monitor change of BLE scan only mode settings.
638 private void registerForBleScanModeChange() {
639 ContentObserver contentObserver = new ContentObserver(null) {
640 @Override
641 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800642 if (isBleScanAlwaysAvailable()) {
643 // Nothing to do
644 return;
645 }
646 // BLE scan is not available.
647 disableBleScanMode();
648 clearBleApps();
649 try {
650 mBluetoothLock.readLock().lock();
651 if (mBluetooth != null) mBluetooth.onBrEdrDown();
652 } catch (RemoteException e) {
653 Slog.e(TAG, "error when disabling bluetooth", e);
654 } finally {
655 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700656 }
657 }
658 };
659
660 mContentResolver.registerContentObserver(
661 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE),
662 false, contentObserver);
663 }
664
665 // Disable ble scan only mode.
666 private void disableBleScanMode() {
667 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700668 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700669 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700670 if (DBG) Slog.d(TAG, "Reseting the mEnable flag for clean disable");
Wei Wange4a744b2015-06-11 17:50:29 -0700671 mEnable = false;
672 }
673 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700674 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700675 } finally {
676 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700677 }
678 }
679
Marie Janssen59804562016-12-28 14:13:21 -0800680 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
681 ClientDeathRecipient r = mBleApps.get(token);
682 if (r == null && enable) {
683 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
684 try {
685 token.linkToDeath(deathRec, 0);
686 } catch (RemoteException ex) {
687 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800688 }
Marie Janssen59804562016-12-28 14:13:21 -0800689 mBleApps.put(token, deathRec);
690 if (DBG) Slog.d(TAG, "Registered for death of " + packageName);
691 } else if (!enable && r != null) {
692 // Unregister death recipient as the app goes away.
693 token.unlinkToDeath(r, 0);
694 mBleApps.remove(token);
695 if (DBG) Slog.d(TAG, "Unregistered for death of " + packageName);
Nitin Arorad055adb2015-03-02 15:03:51 -0800696 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800697 int appCount = mBleApps.size();
698 if (DBG) Slog.d(TAG, appCount + " registered Ble Apps");
699 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700700 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800701 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800702 if (appCount == 0 && !mEnableExternal) {
703 sendBrEdrDownCallback();
704 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800705 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800706 }
707
Wei Wange4a744b2015-06-11 17:50:29 -0700708 // Clear all apps using BLE scan only mode.
709 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800710 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700711 }
712
Marie Janssen59804562016-12-28 14:13:21 -0800713 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800714 public boolean isBleAppPresent() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800715 if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
716 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800717 }
718
719 /**
Marie Janssenfa630682016-12-15 13:51:30 -0800720 * Action taken when GattService is turned on
Nitin Arorad055adb2015-03-02 15:03:51 -0800721 */
722 private void onBluetoothGattServiceUp() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700723 if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700724 try {
725 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800726 if (mBluetooth == null) {
727 if (DBG) Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!");
728 return;
729 }
730 int st = mBluetooth.getState();
731 if (st != BluetoothAdapter.STATE_BLE_ON) {
732 if (DBG) Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " +
733 BluetoothAdapter.nameForState(st));
734 return;
735 }
736 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
737 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800738 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800740 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700741 } catch (RemoteException e) {
742 Slog.e(TAG,"Unable to call onServiceUp", e);
743 } finally {
744 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800745 }
746 }
747
748 /**
749 * Inform BluetoothAdapter instances that BREDR part is down
750 * and turn off all service and stack if no LE app needs it
751 */
752 private void sendBrEdrDownCallback() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700753 if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700754
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700755 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700756 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700757 return;
758 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800759
Martin Brabhamc2b06222017-02-27 16:55:07 -0800760 if (isBleAppPresent()) {
761 // Need to stay at BLE ON. Disconnect all Gatt connections
762 try {
763 mBluetoothGatt.unregAll();
764 } catch (RemoteException e) {
765 Slog.e(TAG, "Unable to disconnect all apps.", e);
766 }
767 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800768 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700769 mBluetoothLock.readLock().lock();
770 if (mBluetooth != null) mBluetooth.onBrEdrDown();
771 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700772 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700773 } finally {
774 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800775 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800777
Nitin Arorad055adb2015-03-02 15:03:51 -0800778 }
779
Marie Janssen59804562016-12-28 14:13:21 -0800780 public boolean enableNoAutoConnect(String packageName)
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700781 {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100782 if (isBluetoothDisallowed()) {
783 if (DBG) {
784 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
785 }
786 return false;
787 }
788
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700789 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
790 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700791
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700792 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700793 Slog.d(TAG,"enableNoAutoConnect(): mBluetooth =" + mBluetooth +
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700794 " mBinding = " + mBinding);
795 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800796 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
797
798 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700799 throw new SecurityException("no permission to enable Bluetooth quietly");
800 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800801
Zhihai Xu401202b2012-12-03 11:36:21 -0800802 synchronized(mReceiver) {
803 mQuietEnableExternal = true;
804 mEnableExternal = true;
Marie Janssen59804562016-12-28 14:13:21 -0800805 sendEnableMsg(true, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800806 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700807 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700808 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700809
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700810 public boolean enable(String packageName) throws RemoteException {
811 final int callingUid = Binder.getCallingUid();
812 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
813
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100814 if (isBluetoothDisallowed()) {
815 if (DBG) {
816 Slog.d(TAG,"enable(): not enabling - bluetooth disallowed");
817 }
818 return false;
819 }
820
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700821 if (!callerSystem) {
822 if (!checkIfCallerIsForegroundUser()) {
823 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
824 return false;
825 }
826
827 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
828 "Need BLUETOOTH ADMIN permission");
829
830 if (!isEnabled() && mPermissionReviewRequired
831 && startConsentUiIfNeeded(packageName, callingUid,
832 BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
833 return false;
834 }
fredcf2458862012-04-16 15:18:27 -0700835 }
836
Zhihai Xu401202b2012-12-03 11:36:21 -0800837 if (DBG) {
Marie Janssen59804562016-12-28 14:13:21 -0800838 Slog.d(TAG,"enable(" + packageName + "): mBluetooth =" + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800839 " mBinding = " + mBinding + " mState = " +
840 BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700841 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800842
843 synchronized(mReceiver) {
844 mQuietEnableExternal = false;
845 mEnableExternal = true;
846 // waive WRITE_SECURE_SETTINGS permission check
Marie Janssen59804562016-12-28 14:13:21 -0800847 sendEnableMsg(false, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800848 }
Jeff Sharkey67609c72016-03-05 14:29:13 -0700849 if (DBG) Slog.d(TAG, "enable returning");
Zhihai Xu401202b2012-12-03 11:36:21 -0800850 return true;
fredc0f420372012-04-12 00:02:00 -0700851 }
852
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700853 public boolean disable(String packageName, boolean persist) throws RemoteException {
854 final int callingUid = Binder.getCallingUid();
855 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700856
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700857 if (!callerSystem) {
858 if (!checkIfCallerIsForegroundUser()) {
859 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
860 return false;
861 }
862
863 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
864 "Need BLUETOOTH ADMIN permission");
865
866 if (isEnabled() && mPermissionReviewRequired
867 && startConsentUiIfNeeded(packageName, callingUid,
868 BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
869 return false;
870 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700871 }
872
fredcf2458862012-04-16 15:18:27 -0700873 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700874 Slog.d(TAG,"disable(): mBluetooth = " + mBluetooth +
Matthew Xiecdce0b92012-07-12 19:06:15 -0700875 " mBinding = " + mBinding);
876 }
fredcf2458862012-04-16 15:18:27 -0700877
Zhihai Xu401202b2012-12-03 11:36:21 -0800878 synchronized(mReceiver) {
879 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800880 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800881 }
882 mEnableExternal = false;
Marie Janssen59804562016-12-28 14:13:21 -0800883 sendDisableMsg(packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800884 }
fredc0f420372012-04-12 00:02:00 -0700885 return true;
886 }
887
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700888 private boolean startConsentUiIfNeeded(String packageName,
889 int callingUid, String intentAction) throws RemoteException {
890 try {
891 // Validate the package only if we are going to use it
892 ApplicationInfo applicationInfo = mContext.getPackageManager()
893 .getApplicationInfoAsUser(packageName,
894 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
895 UserHandle.getUserId(callingUid));
896 if (applicationInfo.uid != callingUid) {
897 throw new SecurityException("Package " + callingUid
898 + " not in uid " + callingUid);
899 }
900
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000901 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000902 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
903 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
904 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
905 try {
906 mContext.startActivity(intent);
907 } catch (ActivityNotFoundException e) {
908 // Shouldn't happen
909 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
910 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700911 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000912 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700913 } catch (PackageManager.NameNotFoundException e) {
914 throw new RemoteException(e.getMessage());
915 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700916 }
917
fredc649fe492012-04-19 01:07:18 -0700918 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700919 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700920 Slog.d(TAG,"unbindAndFinish(): " + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800921 " mBinding = " + mBinding + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -0700922 }
923
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700924 try {
925 mBluetoothLock.writeLock().lock();
fredc0f420372012-04-12 00:02:00 -0700926 if (mUnbinding) return;
927 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -0700928 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -0700929 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -0700930 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -0800931 //Unregister callback object
932 try {
933 mBluetooth.unregisterCallback(mBluetoothCallback);
934 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700935 Slog.e(TAG, "Unable to unregister BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -0700936 }
Marie Janssen9db28eb2016-01-12 16:05:15 -0800937 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -0700938 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -0700939 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -0700940 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700941 mBinding = false;
fredcf2458862012-04-16 15:18:27 -0700942 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -0800943 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -0700944 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800945 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700946 } finally {
947 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700948 }
949 }
950
Matthew Xieddf7e472013-03-01 18:41:02 -0800951 public IBluetoothGatt getBluetoothGatt() {
952 // sync protection
953 return mBluetoothGatt;
954 }
955
Benjamin Franze8b98922014-11-12 15:57:54 +0000956 @Override
957 public boolean bindBluetoothProfileService(int bluetoothProfile,
958 IBluetoothProfileServiceConnection proxy) {
959 if (!mEnable) {
960 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700961 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile +
Benjamin Franze8b98922014-11-12 15:57:54 +0000962 ", while Bluetooth was disabled");
963 }
964 return false;
965 }
966 synchronized (mProfileServices) {
967 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
968 if (psc == null) {
969 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700970 Slog.d(TAG, "Creating new ProfileServiceConnections object for"
Benjamin Franze8b98922014-11-12 15:57:54 +0000971 + " profile: " + bluetoothProfile);
972 }
Benjamin Franz5b614592014-12-09 18:58:45 +0000973
974 if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
975
976 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +0000977 psc = new ProfileServiceConnections(intent);
Benjamin Franz5b614592014-12-09 18:58:45 +0000978 if (!psc.bindService()) return false;
979
Benjamin Franze8b98922014-11-12 15:57:54 +0000980 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +0000981 }
982 }
983
984 // Introducing a delay to give the client app time to prepare
985 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
986 addProxyMsg.arg1 = bluetoothProfile;
987 addProxyMsg.obj = proxy;
988 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
989 return true;
990 }
991
992 @Override
993 public void unbindBluetoothProfileService(int bluetoothProfile,
994 IBluetoothProfileServiceConnection proxy) {
995 synchronized (mProfileServices) {
996 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
997 if (psc == null) {
998 return;
999 }
1000 psc.removeProxy(proxy);
1001 }
1002 }
1003
1004 private void unbindAllBluetoothProfileServices() {
1005 synchronized (mProfileServices) {
1006 for (Integer i : mProfileServices.keySet()) {
1007 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001008 try {
1009 mContext.unbindService(psc);
1010 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001011 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001012 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001013 psc.removeAllProxies();
1014 }
1015 mProfileServices.clear();
1016 }
1017 }
1018
1019 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001020 * Send enable message and set adapter name and address. Called when the boot phase becomes
1021 * PHASE_SYSTEM_SERVICES_READY.
1022 */
1023 public void handleOnBootPhase() {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001024 if (DBG) Slog.d(TAG, "Bluetooth boot completed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001025 UserManagerInternal userManagerInternal =
1026 LocalServices.getService(UserManagerInternal.class);
1027 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001028 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001029 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001030 return;
1031 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001032 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001033 if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
Ajay Panicker467bc042017-02-22 12:23:15 -08001034 sendEnableMsg(mQuietEnableExternal, REASON_SYSTEM_BOOT);
Ajay Panickerbf796d82016-03-11 13:47:20 -08001035 } else if (!isNameAndAddressSet()) {
1036 if (DBG) Slog.d(TAG, "Getting adapter name and address");
Ajay Panicker4bb48302016-03-31 14:14:27 -07001037 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1038 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001039 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001040 }
1041
1042 /**
1043 * Called when switching to a different foreground user.
1044 */
1045 public void handleOnSwitchUser(int userHandle) {
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001046 if (DBG) Slog.d(TAG, "User " + userHandle + " switched");
1047 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1048 }
1049
1050 /**
1051 * Called when user is unlocked.
1052 */
1053 public void handleOnUnlockUser(int userHandle) {
1054 if (DBG) Slog.d(TAG, "User " + userHandle + " unlocked");
1055 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001056 }
1057
1058 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001059 * This class manages the clients connected to a given ProfileService
1060 * and maintains the connection with that service.
1061 */
1062 final private class ProfileServiceConnections implements ServiceConnection,
1063 IBinder.DeathRecipient {
1064 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
1065 new RemoteCallbackList <IBluetoothProfileServiceConnection>();
1066 IBinder mService;
1067 ComponentName mClassName;
1068 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001069 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001070
1071 ProfileServiceConnections(Intent intent) {
1072 mService = null;
1073 mClassName = null;
1074 mIntent = intent;
1075 }
1076
Benjamin Franz5b614592014-12-09 18:58:45 +00001077 private boolean bindService() {
1078 if (mIntent != null && mService == null &&
1079 doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001080 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1081 msg.obj = this;
1082 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001083 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001084 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001085 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001086 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001087 }
1088
1089 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1090 mProxies.register(proxy);
1091 if (mService != null) {
1092 try{
1093 proxy.onServiceConnected(mClassName, mService);
1094 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001095 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001096 }
1097 } else {
1098 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1099 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1100 msg.obj = this;
1101 mHandler.sendMessage(msg);
1102 }
1103 }
1104 }
1105
1106 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1107 if (proxy != null) {
1108 if (mProxies.unregister(proxy)) {
1109 try {
1110 proxy.onServiceDisconnected(mClassName);
1111 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001112 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001113 }
1114 }
1115 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001116 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001117 }
1118 }
1119
1120 private void removeAllProxies() {
1121 onServiceDisconnected(mClassName);
1122 mProxies.kill();
1123 }
1124
1125 @Override
1126 public void onServiceConnected(ComponentName className, IBinder service) {
1127 // remove timeout message
1128 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1129 mService = service;
1130 mClassName = className;
1131 try {
1132 mService.linkToDeath(this, 0);
1133 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001134 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001135 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001136
1137 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001138 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001139 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001140 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001141 mInvokingProxyCallbacks = true;
1142
1143 final int n = mProxies.beginBroadcast();
1144 try {
1145 for (int i = 0; i < n; i++) {
1146 try {
1147 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1148 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001149 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001150 }
1151 }
1152 } finally {
1153 mProxies.finishBroadcast();
1154 mInvokingProxyCallbacks = false;
1155 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001156 }
1157
1158 @Override
1159 public void onServiceDisconnected(ComponentName className) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001160 if (mService == null) return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001161 mService.unlinkToDeath(this, 0);
1162 mService = null;
1163 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001164
1165 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001166 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001167 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001168 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001169 mInvokingProxyCallbacks = true;
1170
1171 final int n = mProxies.beginBroadcast();
1172 try {
1173 for (int i = 0; i < n; i++) {
1174 try {
1175 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1176 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001177 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001178 }
1179 }
1180 } finally {
1181 mProxies.finishBroadcast();
1182 mInvokingProxyCallbacks = false;
1183 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001184 }
1185
1186 @Override
1187 public void binderDied() {
1188 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001189 Slog.w(TAG, "Profile service for profile: " + mClassName
Benjamin Franze8b98922014-11-12 15:57:54 +00001190 + " died.");
1191 }
1192 onServiceDisconnected(mClassName);
1193 // Trigger rebind
1194 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1195 msg.obj = this;
1196 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1197 }
1198 }
1199
fredcbf072a72012-05-09 16:52:50 -07001200 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001201 try {
1202 int n = mStateChangeCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001203 if (DBG) Slog.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001204 for (int i=0; i <n;i++) {
1205 try {
1206 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1207 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001208 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001209 }
fredcbf072a72012-05-09 16:52:50 -07001210 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001211 } finally {
1212 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001213 }
fredcbf072a72012-05-09 16:52:50 -07001214 }
1215
1216 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001217 * Inform BluetoothAdapter instances that Adapter service is up
1218 */
1219 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001220 try {
1221 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001222 Slog.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001223 for (int i=0; i <n;i++) {
1224 try {
1225 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
1226 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001227 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001228 }
1229 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001230 } finally {
1231 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001232 }
1233 }
1234 /**
fredcbf072a72012-05-09 16:52:50 -07001235 * Inform BluetoothAdapter instances that Adapter service is down
1236 */
1237 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001238 try {
1239 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001240 Slog.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001241 for (int i=0; i <n;i++) {
1242 try {
1243 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
1244 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001245 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001246 }
1247 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001248 } finally {
1249 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001250 }
1251 }
Svet Ganov408abf72015-05-12 19:13:36 -07001252
fredc0f420372012-04-12 00:02:00 -07001253 public String getAddress() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001254 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
Svet Ganov408abf72015-05-12 19:13:36 -07001255 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001256
Zhihai Xu6eb76522012-11-29 15:41:04 -08001257 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
Svet Ganov408abf72015-05-12 19:13:36 -07001258 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001259 Slog.w(TAG,"getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001260 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001261 }
1262
Svet Ganov408abf72015-05-12 19:13:36 -07001263 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1264 != PackageManager.PERMISSION_GRANTED) {
1265 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1266 }
1267
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001268 try {
1269 mBluetoothLock.readLock().lock();
1270 if (mBluetooth != null) return mBluetooth.getAddress();
1271 } catch (RemoteException e) {
1272 Slog.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e);
1273 } finally {
1274 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001275 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001276
Matthew Xiecdce0b92012-07-12 19:06:15 -07001277 // mAddress is accessed from outside.
1278 // It is alright without a lock. Here, bluetooth is off, no other thread is
1279 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001280 return mAddress;
1281 }
fredc649fe492012-04-19 01:07:18 -07001282
fredc0f420372012-04-12 00:02:00 -07001283 public String getName() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001284 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
1285 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001286
Zhihai Xu6eb76522012-11-29 15:41:04 -08001287 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
1288 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001289 Slog.w(TAG,"getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001290 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001291 }
1292
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001293 try {
1294 mBluetoothLock.readLock().lock();
1295 if (mBluetooth != null) return mBluetooth.getName();
1296 } catch (RemoteException e) {
1297 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1298 } finally {
1299 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001300 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001301
Matthew Xiecdce0b92012-07-12 19:06:15 -07001302 // mName is accessed from outside.
1303 // It alright without a lock. Here, bluetooth is off, no other thread is
1304 // changing mName
fredc0f420372012-04-12 00:02:00 -07001305 return mName;
1306 }
1307
fredc0f420372012-04-12 00:02:00 -07001308 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001309 public void onServiceConnected(ComponentName componentName, IBinder service) {
1310 String name = componentName.getClassName();
1311 if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
fredc0f420372012-04-12 00:02:00 -07001312 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001313 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001314 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001315 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001316 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1317 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001318 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001319 return;
1320 }
fredc0f420372012-04-12 00:02:00 -07001321 msg.obj = service;
1322 mHandler.sendMessage(msg);
1323 }
1324
Marie Janssencb21ad72016-12-13 10:51:02 -08001325 public void onServiceDisconnected(ComponentName componentName) {
1326 // Called if we unexpectedly disconnect.
1327 String name = componentName.getClassName();
1328 if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
fredc0f420372012-04-12 00:02:00 -07001329 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001330 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001331 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001332 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001333 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1334 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001335 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001336 return;
1337 }
fredc0f420372012-04-12 00:02:00 -07001338 mHandler.sendMessage(msg);
1339 }
1340 }
1341
1342 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1343
Zhihai Xu40874a02012-10-08 17:57:03 -07001344 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001345 boolean mGetNameAddressOnly = false;
1346
Zhihai Xu40874a02012-10-08 17:57:03 -07001347 public BluetoothHandler(Looper looper) {
1348 super(looper);
1349 }
1350
fredc0f420372012-04-12 00:02:00 -07001351 @Override
1352 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001353 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001354 case MESSAGE_GET_NAME_AND_ADDRESS:
1355 if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001356 try {
1357 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001358 if ((mBluetooth == null) && (!mBinding)) {
1359 if (DBG) Slog.d(TAG, "Binding to service to get name and address");
1360 mGetNameAddressOnly = true;
1361 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1362 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1363 Intent i = new Intent(IBluetooth.class.getName());
1364 if (!doBind(i, mConnection,
1365 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1366 UserHandle.CURRENT)) {
1367 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1368 } else {
1369 mBinding = true;
1370 }
1371 } else if (mBluetooth != null) {
1372 try {
1373 storeNameAndAddress(mBluetooth.getName(),
1374 mBluetooth.getAddress());
1375 } catch (RemoteException re) {
1376 Slog.e(TAG, "Unable to grab names", re);
1377 }
1378 if (mGetNameAddressOnly && !mEnable) {
1379 unbindAndFinish();
1380 }
1381 mGetNameAddressOnly = false;
1382 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001383 } finally {
1384 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001385 }
1386 break;
1387
Matthew Xiecdce0b92012-07-12 19:06:15 -07001388 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001389 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001390 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001391 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001392 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1393 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001394
1395 // Use service interface to get the exact state
1396 try {
1397 mBluetoothLock.readLock().lock();
1398 if (mBluetooth != null) {
1399 int state = mBluetooth.getState();
1400 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001401 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001402 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001403 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001404 break;
1405 }
1406 }
1407 } catch (RemoteException e) {
1408 Slog.e(TAG, "", e);
1409 } finally {
1410 mBluetoothLock.readLock().unlock();
1411 }
1412
1413 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001414 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001415 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001416 } else {
1417 //
1418 // We need to wait until transitioned to STATE_OFF and
1419 // the previous Bluetooth process has exited. The
1420 // waiting period has three components:
1421 // (a) Wait until the local state is STATE_OFF. This
1422 // is accomplished by "waitForOnOff(false, true)".
1423 // (b) Wait until the STATE_OFF state is updated to
1424 // all components.
1425 // (c) Wait until the Bluetooth process exits, and
1426 // ActivityManager detects it.
1427 // The waiting for (b) and (c) is accomplished by
1428 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1429 // message. On slower devices, that delay needs to be
1430 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1431 //
1432 waitForOnOff(false, true);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001433 Message restartMsg = mHandler.obtainMessage(
1434 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1435 mHandler.sendMessageDelayed(restartMsg,
1436 2 * SERVICE_RESTART_TIME_MS);
1437 }
fredc649fe492012-04-19 01:07:18 -07001438 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001439
fredc0f420372012-04-12 00:02:00 -07001440 case MESSAGE_DISABLE:
Marie Janssencb21ad72016-12-13 10:51:02 -08001441 if (DBG) Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
Zhihai Xu40874a02012-10-08 17:57:03 -07001442 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1443 if (mEnable && mBluetooth != null) {
1444 waitForOnOff(true, false);
1445 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001446 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001447 waitForOnOff(false, false);
1448 } else {
1449 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001450 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001451 }
fredc0f420372012-04-12 00:02:00 -07001452 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001453
Stanley Tng873b5702017-05-01 21:27:31 -07001454 case MESSAGE_RESTORE_USER_SETTING:
1455 try {
1456 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1457 if (DBG) Slog.d(TAG, "Restore Bluetooth state to disabled");
1458 disable(REASON_RESTORE_USER_SETTING, true);
1459 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1460 if (DBG) Slog.d(TAG, "Restore Bluetooth state to enabled");
1461 enable(REASON_RESTORE_USER_SETTING);
1462 }
1463 } catch (RemoteException e) {
1464 Slog.e(TAG,"Unable to change Bluetooth On setting", e);
1465 }
1466 break;
1467
fredc0f420372012-04-12 00:02:00 -07001468 case MESSAGE_REGISTER_ADAPTER:
1469 {
1470 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001471 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001472 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001473 }
fredc0f420372012-04-12 00:02:00 -07001474 case MESSAGE_UNREGISTER_ADAPTER:
1475 {
1476 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001477 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001478 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001479 }
fredc0f420372012-04-12 00:02:00 -07001480 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
1481 {
1482 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001483 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001484 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001485 }
fredc0f420372012-04-12 00:02:00 -07001486 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK:
1487 {
1488 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001489 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001490 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001491 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001492 case MESSAGE_ADD_PROXY_DELAYED:
1493 {
1494 ProfileServiceConnections psc = mProfileServices.get(
1495 new Integer(msg.arg1));
1496 if (psc == null) {
1497 break;
1498 }
1499 IBluetoothProfileServiceConnection proxy =
1500 (IBluetoothProfileServiceConnection) msg.obj;
1501 psc.addProxy(proxy);
1502 break;
1503 }
1504 case MESSAGE_BIND_PROFILE_SERVICE:
1505 {
1506 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1507 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1508 if (psc == null) {
1509 break;
1510 }
1511 psc.bindService();
1512 break;
1513 }
fredc0f420372012-04-12 00:02:00 -07001514 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
1515 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001516 if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
fredc0f420372012-04-12 00:02:00 -07001517
1518 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001519 try {
1520 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001521 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001522 mBluetoothGatt = IBluetoothGatt.Stub
1523 .asInterface(Binder.allowBlocking(service));
Nitin Arorad055adb2015-03-02 15:03:51 -08001524 onBluetoothGattServiceUp();
Matthew Xieddf7e472013-03-01 18:41:02 -08001525 break;
1526 } // else must be SERVICE_IBLUETOOTH
1527
1528 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001529 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001530
fredc0f420372012-04-12 00:02:00 -07001531 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001532 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001533 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001534
Ajay Panicker4bb48302016-03-31 14:14:27 -07001535 if (!isNameAndAddressSet()) {
1536 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1537 mHandler.sendMessage(getMsg);
1538 if (mGetNameAddressOnly) return;
1539 }
1540
Matthew Xiecdce0b92012-07-12 19:06:15 -07001541 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001542 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001543 mBluetooth.registerCallback(mBluetoothCallback);
1544 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001545 Slog.e(TAG, "Unable to register BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -07001546 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001547 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001548 sendBluetoothServiceUpCallback();
1549
Matthew Xiecdce0b92012-07-12 19:06:15 -07001550 //Do enable request
1551 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001552 if (mQuietEnable == false) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001553 if (!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001554 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001555 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001556 } else {
1557 if (!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001558 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001559 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001560 }
1561 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001562 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001563 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001564 } finally {
1565 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001566 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001567
1568 if (!mEnable) {
1569 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001570 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001571 waitForOnOff(false, false);
1572 }
fredc649fe492012-04-19 01:07:18 -07001573 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001574 }
fredcbf072a72012-05-09 16:52:50 -07001575 case MESSAGE_BLUETOOTH_STATE_CHANGE:
fredc0f420372012-04-12 00:02:00 -07001576 {
fredcbf072a72012-05-09 16:52:50 -07001577 int prevState = msg.arg1;
1578 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001579 if (DBG) {
1580 Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(prevState) + " > " +
1581 BluetoothAdapter.nameForState(newState));
1582 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001583 mState = newState;
1584 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001585 // handle error state transition case from TURNING_ON to OFF
1586 // unbind and rebind bluetooth service and enable bluetooth
Nitin Arorad055adb2015-03-02 15:03:51 -08001587 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001588 (newState == BluetoothAdapter.STATE_OFF) &&
1589 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001590 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001591 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001592 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001593 (newState == BluetoothAdapter.STATE_BLE_ON) &&
1594 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001595 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001596 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001597 // If we tried to enable BT while BT was in the process of shutting down,
1598 // wait for the BT process to fully tear down and then force a restart
1599 // here. This is a bit of a hack (b/29363429).
1600 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) &&
1601 (newState == BluetoothAdapter.STATE_OFF)) {
1602 if (mEnable) {
1603 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1604 waitForOnOff(false, true);
1605 Message restartMsg = mHandler.obtainMessage(
1606 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1607 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1608 }
1609 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001610 if (newState == BluetoothAdapter.STATE_ON ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001611 newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001612 // bluetooth is working, reset the counter
1613 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001614 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001615 mErrorRecoveryRetryCounter = 0;
1616 }
1617 }
fredc649fe492012-04-19 01:07:18 -07001618 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001619 }
fredc0f420372012-04-12 00:02:00 -07001620 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
1621 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001622 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001623 try {
1624 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001625 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1626 // if service is unbinded already, do nothing and return
1627 if (mBluetooth == null) break;
1628 mBluetooth = null;
1629 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1630 mBluetoothGatt = null;
1631 break;
1632 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001633 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001634 break;
1635 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001636 } finally {
1637 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301638 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001639
Marie Janssene54b4222017-03-16 18:10:59 -07001640 // log the unexpected crash
1641 addCrashLog();
1642 addActiveLog(REASON_UNEXPECTED, false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001643 if (mEnable) {
1644 mEnable = false;
1645 // Send a Bluetooth Restart message
1646 Message restartMsg = mHandler.obtainMessage(
1647 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1648 mHandler.sendMessageDelayed(restartMsg,
1649 SERVICE_RESTART_TIME_MS);
1650 }
1651
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001652 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001653
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001654 // Send BT state broadcast to update
1655 // the BT icon correctly
1656 if ((mState == BluetoothAdapter.STATE_TURNING_ON) ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001657 (mState == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001658 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1659 BluetoothAdapter.STATE_TURNING_OFF);
1660 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001661 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001662 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1663 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
1664 BluetoothAdapter.STATE_OFF);
1665 }
1666
1667 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1668 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001669 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001670 }
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301671 case MESSAGE_RESTART_BLUETOOTH_SERVICE:
1672 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001673 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301674 /* Enable without persisting the setting as
1675 it doesnt change when IBluetooth
1676 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001677 mEnable = true;
Marie Janssene54b4222017-03-16 18:10:59 -07001678 addActiveLog(REASON_RESTARTED, true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001679 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301680 break;
1681 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001682 case MESSAGE_TIMEOUT_BIND: {
1683 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1684 mBluetoothLock.writeLock().lock();
1685 mBinding = false;
1686 mBluetoothLock.writeLock().unlock();
1687 break;
1688 }
fredc0f420372012-04-12 00:02:00 -07001689 case MESSAGE_TIMEOUT_UNBIND:
1690 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001691 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001692 mBluetoothLock.writeLock().lock();
1693 mUnbinding = false;
1694 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001695 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001696 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001697
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001698 case MESSAGE_USER_SWITCHED: {
1699 if (DBG) Slog.d(TAG, "MESSAGE_USER_SWITCHED");
Zhihai Xu40874a02012-10-08 17:57:03 -07001700 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001701
Zhihai Xu40874a02012-10-08 17:57:03 -07001702 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001703 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001704 try {
1705 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001706 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001707 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001708 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001709 } catch (RemoteException re) {
1710 Slog.e(TAG, "Unable to unregister", re);
1711 } finally {
1712 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001713 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001714
1715 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1716 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1717 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1718 mState = BluetoothAdapter.STATE_OFF;
1719 }
1720 if (mState == BluetoothAdapter.STATE_OFF) {
1721 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1722 mState = BluetoothAdapter.STATE_TURNING_ON;
1723 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001724
1725 waitForOnOff(true, false);
1726
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001727 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1728 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1729 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001730
Benjamin Franze8b98922014-11-12 15:57:54 +00001731 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001732 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07001733 addActiveLog(REASON_USER_SWITCH, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001734 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001735 // Pbap service need receive STATE_TURNING_OFF intent to close
1736 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1737 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001738
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001739 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001740
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001741 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Zhihai Xu40874a02012-10-08 17:57:03 -07001742 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001743 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001744
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001745 try {
1746 mBluetoothLock.writeLock().lock();
1747 if (mBluetooth != null) {
1748 mBluetooth = null;
1749 // Unbind
1750 mContext.unbindService(mConnection);
1751 }
1752 mBluetoothGatt = null;
1753 } finally {
1754 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001755 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001756
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001757 //
1758 // If disabling Bluetooth times out, wait for an
1759 // additional amount of time to ensure the process is
1760 // shut down completely before attempting to restart.
1761 //
1762 if (didDisableTimeout) {
1763 SystemClock.sleep(3000);
1764 } else {
1765 SystemClock.sleep(100);
1766 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001767
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001768 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1769 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001770 // enable
Marie Janssene54b4222017-03-16 18:10:59 -07001771 addActiveLog(REASON_USER_SWITCH, true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001772 // mEnable flag could have been reset on disableBLE. Reenable it.
1773 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001774 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001775 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001776 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1777 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001778 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001779 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1780 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001781 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001782 }
John Spurlock8a985d22014-02-25 09:40:05 -05001783 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001784 break;
1785 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001786 case MESSAGE_USER_UNLOCKED: {
1787 if (DBG) Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1788 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1789
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001790 if (mEnable && !mBinding && (mBluetooth == null)) {
1791 // We should be connected, but we gave up for some
1792 // reason; maybe the Bluetooth service wasn't encryption
1793 // aware, so try binding again.
1794 if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1795 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001796 }
1797 }
fredc0f420372012-04-12 00:02:00 -07001798 }
1799 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001800 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001801
Zhihai Xu401202b2012-12-03 11:36:21 -08001802 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001803 mQuietEnable = quietMode;
1804
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001805 try {
1806 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001807 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001808 //Start bind timeout and bind
1809 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1810 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001811 Intent i = new Intent(IBluetooth.class.getName());
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001812 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1813 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001814 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001815 } else {
1816 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001817 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001818 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001819 //Enable bluetooth
1820 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001821 if (!mQuietEnable) {
1822 if(!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001823 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001824 }
1825 }
1826 else {
1827 if(!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001828 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001829 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001830 }
1831 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001832 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001833 }
1834 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001835 } finally {
1836 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001837 }
1838 }
1839
Dianne Hackborn221ea892013-08-04 16:50:16 -07001840 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1841 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1842 intent.setComponent(comp);
1843 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001844 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001845 return false;
1846 }
1847 return true;
1848 }
1849
Zhihai Xu401202b2012-12-03 11:36:21 -08001850 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001851 try {
1852 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001853 if (mBluetooth != null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001854 if (DBG) Slog.d(TAG,"Sending off request.");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001855 if (!mBluetooth.disable()) {
1856 Slog.e(TAG,"IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001857 }
1858 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001859 } catch (RemoteException e) {
1860 Slog.e(TAG,"Unable to call disable()",e);
1861 } finally {
1862 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001863 }
1864 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001865
1866 private boolean checkIfCallerIsForegroundUser() {
1867 int foregroundUser;
1868 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001869 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07001870 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00001871 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1872 UserInfo ui = um.getProfileParent(callingUser);
1873 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001874 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07001875 boolean valid = false;
1876 try {
1877 foregroundUser = ActivityManager.getCurrentUser();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001878 valid = (callingUser == foregroundUser) ||
Benjamin Franze8b98922014-11-12 15:57:54 +00001879 parentUser == foregroundUser ||
Adrian Roosbd9a9a52014-08-18 15:31:57 +02001880 callingAppId == Process.NFC_UID ||
1881 callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08001882 if (DBG && !valid) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001883 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid
Zhihai Xu40874a02012-10-08 17:57:03 -07001884 + " callingUser=" + callingUser
Benjamin Franze8b98922014-11-12 15:57:54 +00001885 + " parentUser=" + parentUser
Zhihai Xu40874a02012-10-08 17:57:03 -07001886 + " foregroundUser=" + foregroundUser);
1887 }
1888 } finally {
1889 Binder.restoreCallingIdentity(callingIdentity);
1890 }
1891 return valid;
1892 }
1893
Nitin Arorad055adb2015-03-02 15:03:51 -08001894 private void sendBleStateChanged(int prevState, int newState) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001895 if (DBG) Slog.d(TAG,"Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) +
1896 " > " + BluetoothAdapter.nameForState(newState));
Nitin Arorad055adb2015-03-02 15:03:51 -08001897 // Send broadcast message to everyone else
1898 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
1899 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1900 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1901 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1902 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
1903 }
1904
Zhihai Xu40874a02012-10-08 17:57:03 -07001905 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001906 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08001907 if (prevState == newState) { // No change. Nothing to do.
1908 return;
1909 }
1910 // Notify all proxy objects first of adapter state change
1911 if (newState == BluetoothAdapter.STATE_BLE_ON ||
1912 newState == BluetoothAdapter.STATE_OFF) {
1913 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
1914 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07001915
Marie Janssencb21ad72016-12-13 10:51:02 -08001916 if (newState == BluetoothAdapter.STATE_OFF) {
1917 // If Bluetooth is off, send service down event to proxy objects, and unbind
1918 if (DBG) Slog.d(TAG, "Bluetooth is complete send Service Down");
1919 sendBluetoothServiceDownCallback();
1920 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08001921 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08001922 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08001923 isStandardBroadcast = false;
1924
Marie Janssencb21ad72016-12-13 10:51:02 -08001925 } else if (!intermediate_off) {
1926 // connect to GattService
1927 if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode");
1928 if (mBluetoothGatt != null) {
1929 if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp");
1930 onBluetoothGattServiceUp();
1931 } else {
1932 if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service");
1933 if (mContext.getPackageManager().hasSystemFeature(
1934 PackageManager.FEATURE_BLUETOOTH_LE)) {
1935 Intent i = new Intent(IBluetoothGatt.class.getName());
1936 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT);
1937 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001938 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001939 sendBleStateChanged(prevState, newState);
1940 //Don't broadcase this as std intent
1941 isStandardBroadcast = false;
1942
1943 } else if (intermediate_off) {
1944 if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode");
1945 // For LE only mode, broadcast as is
1946 sendBleStateChanged(prevState, newState);
1947 sendBluetoothStateCallback(false); // BT is OFF for general users
1948 // Broadcast as STATE_OFF
1949 newState = BluetoothAdapter.STATE_OFF;
1950 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08001951 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001952 } else if (newState == BluetoothAdapter.STATE_ON) {
1953 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
1954 sendBluetoothStateCallback(isUp);
1955 sendBleStateChanged(prevState, newState);
1956
1957 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON ||
1958 newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) {
1959 sendBleStateChanged(prevState, newState);
1960 isStandardBroadcast = false;
1961
1962 } else if (newState == BluetoothAdapter.STATE_TURNING_ON ||
1963 newState == BluetoothAdapter.STATE_TURNING_OFF) {
1964 sendBleStateChanged(prevState, newState);
1965 }
1966
1967 if (isStandardBroadcast) {
1968 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
1969 // Show prevState of BLE_ON as OFF to standard users
1970 prevState = BluetoothAdapter.STATE_OFF;
1971 }
1972 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
1973 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1974 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1975 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1976 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07001977 }
1978 }
1979
1980 /**
1981 * if on is true, wait for state become ON
1982 * if off is true, wait for state become OFF
1983 * if both on and off are false, wait for state not ON
1984 */
1985 private boolean waitForOnOff(boolean on, boolean off) {
1986 int i = 0;
1987 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001988 try {
1989 mBluetoothLock.readLock().lock();
1990 if (mBluetooth == null) break;
1991 if (on) {
1992 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true;
1993 } else if (off) {
1994 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true;
1995 } else {
1996 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true;
Zhihai Xu40874a02012-10-08 17:57:03 -07001997 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001998 } catch (RemoteException e) {
1999 Slog.e(TAG, "getState()", e);
2000 break;
2001 } finally {
2002 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002003 }
2004 if (on || off) {
2005 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002006 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002007 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002008 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002009 i++;
2010 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07002011 Slog.e(TAG,"waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002012 return false;
2013 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002014
Marie Janssen59804562016-12-28 14:13:21 -08002015 private void sendDisableMsg(String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002016 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Marie Janssen59804562016-12-28 14:13:21 -08002017 addActiveLog(packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002018 }
2019
Marie Janssen59804562016-12-28 14:13:21 -08002020 private void sendEnableMsg(boolean quietMode, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002021 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
2022 quietMode ? 1 : 0, 0));
Marie Janssen59804562016-12-28 14:13:21 -08002023 addActiveLog(packageName, true);
2024 }
2025
2026 private void addActiveLog(String packageName, boolean enable) {
2027 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002028 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002029 mActiveLogs.remove();
2030 }
2031 mActiveLogs.add(new ActiveLog(packageName, enable, System.currentTimeMillis()));
2032 }
Zhihai Xu401202b2012-12-03 11:36:21 -08002033 }
2034
Marie Janssene54b4222017-03-16 18:10:59 -07002035 private void addCrashLog() {
2036 synchronized (mCrashTimestamps) {
2037 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) mCrashTimestamps.removeFirst();
2038 mCrashTimestamps.add(System.currentTimeMillis());
2039 mCrashes++;
2040 }
2041 }
2042
Marie Janssen2977c3e2016-11-09 12:01:24 -08002043 private void recoverBluetoothServiceFromError(boolean clearBle) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07002044 Slog.e(TAG,"recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002045 try {
2046 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002047 if (mBluetooth != null) {
2048 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002049 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002050 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002051 } catch (RemoteException re) {
2052 Slog.e(TAG, "Unable to unregister", re);
2053 } finally {
2054 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002055 }
2056
2057 SystemClock.sleep(500);
2058
2059 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07002060 addActiveLog(REASON_START_CRASH, false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002061 handleDisable();
2062
2063 waitForOnOff(false, true);
2064
2065 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002066
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002067 try {
2068 mBluetoothLock.writeLock().lock();
2069 if (mBluetooth != null) {
2070 mBluetooth = null;
2071 // Unbind
2072 mContext.unbindService(mConnection);
2073 }
2074 mBluetoothGatt = null;
2075 } finally {
2076 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002077 }
2078
2079 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2080 mState = BluetoothAdapter.STATE_OFF;
2081
Marie Janssen2977c3e2016-11-09 12:01:24 -08002082 if (clearBle) {
2083 clearBleApps();
2084 }
2085
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002086 mEnable = false;
2087
2088 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2089 // Send a Bluetooth Restart message to reenable bluetooth
2090 Message restartMsg = mHandler.obtainMessage(
2091 MESSAGE_RESTART_BLUETOOTH_SERVICE);
2092 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2093 } else {
2094 // todo: notify user to power down and power up phone to make bluetooth work.
2095 }
2096 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002097
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002098 private boolean isBluetoothDisallowed() {
2099 long callingIdentity = Binder.clearCallingIdentity();
2100 try {
2101 return mContext.getSystemService(UserManager.class)
2102 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2103 } finally {
2104 Binder.restoreCallingIdentity(callingIdentity);
2105 }
2106 }
2107
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002108 /**
2109 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002110 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2111 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002112 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002113 * @param userId user to disable bluetooth sharing for.
2114 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002115 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002116 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002117 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2118 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002119 final int newState = bluetoothSharingDisallowed
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002120 ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2121 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2122 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002123 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002124 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2125 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002126 } catch (Exception e) {
2127 // The component was not found, do nothing.
2128 }
2129 }
2130
Mike Lockwood726d4de2014-10-28 14:06:28 -07002131 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002132 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002133 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002134 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002135
2136 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2137
2138 if (!protoOut) {
2139 writer.println("Bluetooth Status");
2140 writer.println(" enabled: " + isEnabled());
2141 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2142 writer.println(" address: " + mAddress);
2143 writer.println(" name: " + mName);
2144 if (mEnable) {
2145 long onDuration = System.currentTimeMillis() - mActiveLogs.getLast().getTime();
2146 String onDurationString = String.format("%02d:%02d:%02d.%03d",
2147 (int)(onDuration / (1000 * 60 * 60)),
2148 (int)((onDuration / (1000 * 60)) % 60),
2149 (int)((onDuration / 1000) % 60),
2150 (int)(onDuration % 1000));
2151 writer.println(" time since enabled: " + onDurationString + "\n");
2152 }
2153
Marie Janssena95924d2017-01-18 09:37:52 -08002154 if (mActiveLogs.size() == 0) {
2155 writer.println("Bluetooth never enabled!");
2156 } else {
2157 writer.println("Enable log:");
2158 for (ActiveLog log : mActiveLogs) {
2159 writer.println(" " + log);
2160 }
Marie Janssen59804562016-12-28 14:13:21 -08002161 }
2162
Marie Janssene54b4222017-03-16 18:10:59 -07002163 writer.println("Bluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2164 if (mCrashes == CRASH_LOG_MAX_SIZE) writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2165 for (Long time : mCrashTimestamps) {
2166 writer.println(" " + timeToLog(time.longValue()));
2167 }
2168
Marie Janssena95924d2017-01-18 09:37:52 -08002169 String bleAppString = "No BLE Apps registered.";
2170 if (mBleApps.size() == 1) {
2171 bleAppString = "1 BLE App registered:";
2172 } else if (mBleApps.size() > 1) {
2173 bleAppString = mBleApps.size() + " BLE Apps registered:";
2174 }
2175 writer.println("\n" + bleAppString);
Marie Janssen59804562016-12-28 14:13:21 -08002176 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002177 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002178 }
2179
Marie Janssena95924d2017-01-18 09:37:52 -08002180 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002181 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002182 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002183 // Add arg to produce output
2184 args = new String[1];
2185 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002186 }
Marie Janssen59804562016-12-28 14:13:21 -08002187 }
2188
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002189 if (mBluetoothBinder == null) {
2190 errorMsg = "Bluetooth Service not connected";
2191 } else {
2192 try {
2193 mBluetoothBinder.dump(fd, args);
2194 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002195 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002196 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002197 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002198 if (errorMsg != null) {
2199 // Silently return if we are extracting metrics in Protobuf format
Marie Janssen59804562016-12-28 14:13:21 -08002200 if (protoOut) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002201 writer.println(errorMsg);
2202 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002203 }
fredc0f420372012-04-12 00:02:00 -07002204}