blob: 04279a31d2bec64b7f0212ae5cef447251c0a62c [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 Janssen12a35012017-06-26 07:21:03 -0700198 private long mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -0800199
200 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800201 // synchronize with broadcast receiver.
202 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800203 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800204
205 // Map of apps registered to keep BLE scanning on.
206 private Map<IBinder, ClientDeathRecipient> mBleApps = new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
207
Zhihai Xu40874a02012-10-08 17:57:03 -0700208 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700209 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800210 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200211 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700212
Benjamin Franze8b98922014-11-12 15:57:54 +0000213 // Save a ProfileServiceConnections object for each of the bound
214 // bluetooth profile services
215 private final Map <Integer, ProfileServiceConnections> mProfileServices =
216 new HashMap <Integer, ProfileServiceConnections>();
217
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700218 private final boolean mPermissionReviewRequired;
219
Marie Janssen59804562016-12-28 14:13:21 -0800220 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700221 @Override
222 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
223 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
224 mHandler.sendMessage(msg);
225 }
226 };
227
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100228 private final UserRestrictionsListener mUserRestrictionsListener =
229 new UserRestrictionsListener() {
230 @Override
231 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
232 Bundle prevRestrictions) {
Myles Watson6291fae2017-06-29 03:12:02 -0700233
234 if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
235 UserManager.DISALLOW_BLUETOOTH_SHARING)) {
236 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
237 UserManager.DISALLOW_BLUETOOTH_SHARING));
Lenka Trochtovac6f0e232017-01-17 10:35:49 +0100238 }
Pavel Grafov4f4f6f82017-03-28 13:44:04 +0100239
Myles Watson6291fae2017-06-29 03:12:02 -0700240 // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
241 if (userId == UserHandle.USER_SYSTEM &&
242 UserRestrictionsUtils.restrictionsChanged(
243 prevRestrictions, newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
244 if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
245 UserManager.DISALLOW_BLUETOOTH)) {
246 updateOppLauncherComponentState(userId, true); // Sharing disallowed
247 sendDisableMsg(REASON_DISALLOWED);
248 } else {
249 updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
250 UserManager.DISALLOW_BLUETOOTH_SHARING));
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100251 }
252 }
253 }
254 };
255
Ajay Panicker467bc042017-02-22 12:23:15 -0800256 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
257 @Override
258 public void onChange(boolean unused) {
259 synchronized(this) {
260 if (isBluetoothPersistedStateOn()) {
261 if (isAirplaneModeOn()) {
262 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
263 } else {
264 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
265 }
266 }
267
268 int st = BluetoothAdapter.STATE_OFF;
269 try {
270 mBluetoothLock.readLock().lock();
271 if (mBluetooth != null) {
272 st = mBluetooth.getState();
273 }
274 } catch (RemoteException e) {
275 Slog.e(TAG, "Unable to call getState", e);
276 return;
277 } finally {
278 mBluetoothLock.readLock().unlock();
279 }
280
281 Slog.d(TAG, "Airplane Mode change - current state: " +
282 BluetoothAdapter.nameForState(st));
283
284 if (isAirplaneModeOn()) {
285 // Clear registered LE apps to force shut-off
286 clearBleApps();
287
288 // If state is BLE_ON make sure we trigger disableBLE
289 if (st == BluetoothAdapter.STATE_BLE_ON) {
290 try {
291 mBluetoothLock.readLock().lock();
292 if (mBluetooth != null) {
293 mBluetooth.onBrEdrDown();
294 mEnable = false;
295 mEnableExternal = false;
296 }
297 } catch (RemoteException e) {
298 Slog.e(TAG,"Unable to call onBrEdrDown", e);
299 } finally {
300 mBluetoothLock.readLock().unlock();
301 }
302 } else if (st == BluetoothAdapter.STATE_ON){
303 sendDisableMsg(REASON_AIRPLANE_MODE);
304 }
305 } else if (mEnableExternal) {
306 sendEnableMsg(mQuietEnableExternal, REASON_AIRPLANE_MODE);
307 }
308 }
309 }
310 };
311
fredcbf072a72012-05-09 16:52:50 -0700312 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700313 @Override
314 public void onReceive(Context context, Intent intent) {
315 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700316 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700317 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700318 if (DBG) Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
fredc0f420372012-04-12 00:02:00 -0700319 if (newName != null) {
320 storeNameAndAddress(newName, null);
321 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700322 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
323 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
324 if (newAddress != null) {
325 if (DBG) Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
326 storeNameAndAddress(null, newAddress);
327 } else {
328 if (DBG) Slog.e(TAG, "No Bluetooth Adapter address parameter found");
329 }
Stanley Tng873b5702017-05-01 21:27:31 -0700330 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
331 final String name = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
332 if (Settings.Global.BLUETOOTH_ON.equals(name)) {
333 // The Bluetooth On state may be changed during system restore.
334 final String prevValue = intent.getStringExtra(
335 Intent.EXTRA_SETTING_PREVIOUS_VALUE);
336 final String newValue = intent.getStringExtra(
337 Intent.EXTRA_SETTING_NEW_VALUE);
338
339 if (DBG) Slog.d(TAG, "ACTION_SETTING_RESTORED with BLUETOOTH_ON, prevValue=" +
340 prevValue + ", newValue=" + newValue);
341
342 if ((newValue != null) && (prevValue != null) && !prevValue.equals(newValue)) {
343 Message msg = mHandler.obtainMessage(MESSAGE_RESTORE_USER_SETTING,
344 newValue.equals("0") ?
345 RESTORE_SETTING_TO_OFF :
346 RESTORE_SETTING_TO_ON, 0);
347 mHandler.sendMessage(msg);
348 }
349 }
fredc0f420372012-04-12 00:02:00 -0700350 }
351 }
352 };
353
354 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700355 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700356
fredc0f420372012-04-12 00:02:00 -0700357 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700358
Svet Ganov77df6f32016-08-17 11:46:34 -0700359 mPermissionReviewRequired = context.getResources().getBoolean(
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700360 com.android.internal.R.bool.config_permissionReviewRequired);
361
Marie Janssen59804562016-12-28 14:13:21 -0800362 mActiveLogs = new LinkedList<ActiveLog>();
Marie Janssene54b4222017-03-16 18:10:59 -0700363 mCrashTimestamps = new LinkedList<Long>();
364 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700365 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800366 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800367 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700368 mBinding = false;
369 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700370 mEnable = false;
371 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800372 mQuietEnableExternal = false;
373 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700374 mAddress = null;
375 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800376 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700377 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700378 // Observe BLE scan only mode settings change.
379 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700380 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
381 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Stanley Tng873b5702017-05-01 21:27:31 -0700382
383 IntentFilter filter = new IntentFilter();
384 filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
385 filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
386 filter.addAction(Intent.ACTION_SETTING_RESTORED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700387 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700388 mContext.registerReceiver(mReceiver, filter);
Stanley Tng873b5702017-05-01 21:27:31 -0700389
fredc0f420372012-04-12 00:02:00 -0700390 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800391 if (isBluetoothPersistedStateOn()) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700392 if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
Zhihai Xu401202b2012-12-03 11:36:21 -0800393 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700394 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200395
Ajay Panicker467bc042017-02-22 12:23:15 -0800396 String airplaneModeRadios = Settings.Global.getString(mContentResolver,
397 Settings.Global.AIRPLANE_MODE_RADIOS);
398 if (airplaneModeRadios == null ||
399 airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
400 mContentResolver.registerContentObserver(
401 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
402 true, mAirplaneModeObserver);
403 }
404
Marie Janssen59804562016-12-28 14:13:21 -0800405 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200406 try {
Marie Janssen59804562016-12-28 14:13:21 -0800407 systemUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui",
Jeff Sharkeyc5967e92016-01-07 18:50:29 -0700408 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200409 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700410 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700411 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200412 }
Marie Janssen59804562016-12-28 14:13:21 -0800413 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700414 }
415
fredc649fe492012-04-19 01:07:18 -0700416 /**
417 * Returns true if airplane mode is currently on
418 */
419 private final boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700420 return Settings.Global.getInt(mContext.getContentResolver(),
421 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700422 }
423
424 /**
425 * Returns true if the Bluetooth saved state is "on"
426 */
427 private final boolean isBluetoothPersistedStateOn() {
Marie Janssen9fa24912016-10-18 10:04:24 -0700428 int state = Settings.Global.getInt(mContentResolver,
429 Settings.Global.BLUETOOTH_ON, -1);
430 if (DBG) Slog.d(TAG, "Bluetooth persisted state: " + state);
431 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800432 }
433
434 /**
435 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
436 */
437 private final boolean isBluetoothPersistedStateOnBluetooth() {
438 return Settings.Global.getInt(mContentResolver,
Andre Eisenbach8c184312016-09-06 18:03:10 -0700439 Settings.Global.BLUETOOTH_ON, BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700440 }
441
442 /**
443 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700444 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800445 private void persistBluetoothSetting(int value) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700446 if (DBG) Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
Marie Janssenfa630682016-12-15 13:51:30 -0800447 // waive WRITE_SECURE_SETTINGS permission check
448 long callingIdentity = Binder.clearCallingIdentity();
Jeff Brownbf6f6f92012-09-25 15:03:20 -0700449 Settings.Global.putInt(mContext.getContentResolver(),
450 Settings.Global.BLUETOOTH_ON,
Zhihai Xu401202b2012-12-03 11:36:21 -0800451 value);
Marie Janssenfa630682016-12-15 13:51:30 -0800452 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700453 }
454
455 /**
456 * Returns true if the Bluetooth Adapter's name and address is
457 * locally cached
458 * @return
459 */
fredc0f420372012-04-12 00:02:00 -0700460 private boolean isNameAndAddressSet() {
461 return mName !=null && mAddress!= null && mName.length()>0 && mAddress.length()>0;
462 }
463
fredc649fe492012-04-19 01:07:18 -0700464 /**
465 * Retrieve the Bluetooth Adapter's name and address and save it in
466 * in the local cache
467 */
fredc0f420372012-04-12 00:02:00 -0700468 private void loadStoredNameAndAddress() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700469 if (DBG) Slog.d(TAG, "Loading stored name and address");
Zhihai Xud31c3222012-10-31 16:08:57 -0700470 if (mContext.getResources().getBoolean
471 (com.android.internal.R.bool.config_bluetooth_address_validation) &&
472 Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0) == 0) {
473 // if the valid flag is not set, don't load the address and name
Jeff Sharkey67609c72016-03-05 14:29:13 -0700474 if (DBG) Slog.d(TAG, "invalid bluetooth name and address stored");
Zhihai Xud31c3222012-10-31 16:08:57 -0700475 return;
476 }
fredc0f420372012-04-12 00:02:00 -0700477 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
478 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700479 if (DBG) Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
fredc0f420372012-04-12 00:02:00 -0700480 }
481
fredc649fe492012-04-19 01:07:18 -0700482 /**
483 * Save the Bluetooth name and address in the persistent store.
484 * Only non-null values will be saved.
485 * @param name
486 * @param address
487 */
fredc0f420372012-04-12 00:02:00 -0700488 private void storeNameAndAddress(String name, String address) {
489 if (name != null) {
490 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700491 mName = name;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700492 if (DBG) Slog.d(TAG,"Stored Bluetooth name: " +
fredc649fe492012-04-19 01:07:18 -0700493 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_NAME));
fredc0f420372012-04-12 00:02:00 -0700494 }
495
496 if (address != null) {
497 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
fredc0f420372012-04-12 00:02:00 -0700498 mAddress=address;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700499 if (DBG) Slog.d(TAG,"Stored Bluetoothaddress: " +
fredc649fe492012-04-19 01:07:18 -0700500 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS));
fredc0f420372012-04-12 00:02:00 -0700501 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700502
503 if ((name != null) && (address != null)) {
504 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
505 }
fredc0f420372012-04-12 00:02:00 -0700506 }
507
508 public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700509 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700510 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700511 return null;
512 }
fredc0f420372012-04-12 00:02:00 -0700513 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
514 msg.obj = callback;
515 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700516
517 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700518 }
519
520 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700521 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700522 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700523 return;
524 }
fredc0f420372012-04-12 00:02:00 -0700525 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
526 "Need BLUETOOTH permission");
527 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
528 msg.obj = callback;
529 mHandler.sendMessage(msg);
530 }
531
532 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
533 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
534 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800535 if (callback == null) {
536 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
537 return;
538 }
fredc0f420372012-04-12 00:02:00 -0700539 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
540 msg.obj = callback;
541 mHandler.sendMessage(msg);
542 }
543
544 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
545 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
546 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800547 if (callback == null) {
548 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
549 return;
550 }
fredc0f420372012-04-12 00:02:00 -0700551 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
552 msg.obj = callback;
553 mHandler.sendMessage(msg);
554 }
555
556 public boolean isEnabled() {
Zhihai Xu6eb76522012-11-29 15:41:04 -0800557 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
558 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700559 Slog.w(TAG,"isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700560 return false;
561 }
562
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700563 try {
564 mBluetoothLock.readLock().lock();
565 if (mBluetooth != null) return mBluetooth.isEnabled();
566 } catch (RemoteException e) {
567 Slog.e(TAG, "isEnabled()", e);
568 } finally {
569 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700570 }
571 return false;
572 }
573
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700574 public int getState() {
575 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
576 (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800577 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700578 return BluetoothAdapter.STATE_OFF;
579 }
580
581 try {
582 mBluetoothLock.readLock().lock();
583 if (mBluetooth != null) return mBluetooth.getState();
584 } catch (RemoteException e) {
585 Slog.e(TAG, "getState()", e);
586 } finally {
587 mBluetoothLock.readLock().unlock();
588 }
589 return BluetoothAdapter.STATE_OFF;
590 }
591
Nitin Arorad055adb2015-03-02 15:03:51 -0800592 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800593 private String mPackageName;
594
595 public ClientDeathRecipient(String packageName) {
596 mPackageName = packageName;
597 }
598
Nitin Arorad055adb2015-03-02 15:03:51 -0800599 public void binderDied() {
Marie Janssen59804562016-12-28 14:13:21 -0800600 if (DBG) Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800601 if (isBleAppPresent()) {
602 // Nothing to do, another app is here.
603 return;
604 }
605 if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
606 try {
607 mBluetoothLock.readLock().lock();
608 if (mBluetooth != null &&
609 mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
610 mEnable = false;
611 mBluetooth.onBrEdrDown();
Nitin Arorad055adb2015-03-02 15:03:51 -0800612 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800613 } catch (RemoteException e) {
614 Slog.e(TAG,"Unable to call onBrEdrDown", e);
615 } finally {
616 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800617 }
618 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800619
Marie Janssen59804562016-12-28 14:13:21 -0800620 public String getPackageName() {
621 return mPackageName;
622 }
623 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800624
Wei Wang67d84162015-04-26 17:04:29 -0700625 @Override
626 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700627 if (isAirplaneModeOn() && !mEnable) {
628 return false;
629 }
Wei Wang67d84162015-04-26 17:04:29 -0700630 try {
631 return (Settings.Global.getInt(mContentResolver,
632 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE)) != 0;
633 } catch (SettingNotFoundException e) {
634 }
635 return false;
636 }
637
Wei Wange4a744b2015-06-11 17:50:29 -0700638 // Monitor change of BLE scan only mode settings.
639 private void registerForBleScanModeChange() {
640 ContentObserver contentObserver = new ContentObserver(null) {
641 @Override
642 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800643 if (isBleScanAlwaysAvailable()) {
644 // Nothing to do
645 return;
646 }
647 // BLE scan is not available.
648 disableBleScanMode();
649 clearBleApps();
650 try {
651 mBluetoothLock.readLock().lock();
652 if (mBluetooth != null) mBluetooth.onBrEdrDown();
653 } catch (RemoteException e) {
654 Slog.e(TAG, "error when disabling bluetooth", e);
655 } finally {
656 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700657 }
658 }
659 };
660
661 mContentResolver.registerContentObserver(
662 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE),
663 false, contentObserver);
664 }
665
666 // Disable ble scan only mode.
667 private void disableBleScanMode() {
668 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700669 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700670 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700671 if (DBG) Slog.d(TAG, "Reseting the mEnable flag for clean disable");
Wei Wange4a744b2015-06-11 17:50:29 -0700672 mEnable = false;
673 }
674 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700675 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700676 } finally {
677 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700678 }
679 }
680
Marie Janssen59804562016-12-28 14:13:21 -0800681 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
682 ClientDeathRecipient r = mBleApps.get(token);
683 if (r == null && enable) {
684 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
685 try {
686 token.linkToDeath(deathRec, 0);
687 } catch (RemoteException ex) {
688 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800689 }
Marie Janssen59804562016-12-28 14:13:21 -0800690 mBleApps.put(token, deathRec);
691 if (DBG) Slog.d(TAG, "Registered for death of " + packageName);
692 } else if (!enable && r != null) {
693 // Unregister death recipient as the app goes away.
694 token.unlinkToDeath(r, 0);
695 mBleApps.remove(token);
696 if (DBG) Slog.d(TAG, "Unregistered for death of " + packageName);
Nitin Arorad055adb2015-03-02 15:03:51 -0800697 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800698 int appCount = mBleApps.size();
699 if (DBG) Slog.d(TAG, appCount + " registered Ble Apps");
700 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700701 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800702 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800703 if (appCount == 0 && !mEnableExternal) {
704 sendBrEdrDownCallback();
705 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800706 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800707 }
708
Wei Wange4a744b2015-06-11 17:50:29 -0700709 // Clear all apps using BLE scan only mode.
710 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800711 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700712 }
713
Marie Janssen59804562016-12-28 14:13:21 -0800714 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800715 public boolean isBleAppPresent() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800716 if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
717 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800718 }
719
720 /**
Marie Janssenfa630682016-12-15 13:51:30 -0800721 * Action taken when GattService is turned on
Nitin Arorad055adb2015-03-02 15:03:51 -0800722 */
723 private void onBluetoothGattServiceUp() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700724 if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700725 try {
726 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800727 if (mBluetooth == null) {
728 if (DBG) Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!");
729 return;
730 }
731 int st = mBluetooth.getState();
732 if (st != BluetoothAdapter.STATE_BLE_ON) {
733 if (DBG) Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " +
734 BluetoothAdapter.nameForState(st));
735 return;
736 }
737 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
738 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800740 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800741 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700742 } catch (RemoteException e) {
743 Slog.e(TAG,"Unable to call onServiceUp", e);
744 } finally {
745 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800746 }
747 }
748
749 /**
750 * Inform BluetoothAdapter instances that BREDR part is down
751 * and turn off all service and stack if no LE app needs it
752 */
753 private void sendBrEdrDownCallback() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700754 if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700755
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700756 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700757 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700758 return;
759 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800760
Martin Brabhamc2b06222017-02-27 16:55:07 -0800761 if (isBleAppPresent()) {
762 // Need to stay at BLE ON. Disconnect all Gatt connections
763 try {
764 mBluetoothGatt.unregAll();
765 } catch (RemoteException e) {
766 Slog.e(TAG, "Unable to disconnect all apps.", e);
767 }
768 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800769 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700770 mBluetoothLock.readLock().lock();
771 if (mBluetooth != null) mBluetooth.onBrEdrDown();
772 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700773 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700774 } finally {
775 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800776 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800777 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800778
Nitin Arorad055adb2015-03-02 15:03:51 -0800779 }
780
Marie Janssen59804562016-12-28 14:13:21 -0800781 public boolean enableNoAutoConnect(String packageName)
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700782 {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100783 if (isBluetoothDisallowed()) {
784 if (DBG) {
785 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
786 }
787 return false;
788 }
789
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700790 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
791 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700792
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700793 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700794 Slog.d(TAG,"enableNoAutoConnect(): mBluetooth =" + mBluetooth +
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700795 " mBinding = " + mBinding);
796 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800797 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
798
799 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700800 throw new SecurityException("no permission to enable Bluetooth quietly");
801 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800802
Zhihai Xu401202b2012-12-03 11:36:21 -0800803 synchronized(mReceiver) {
804 mQuietEnableExternal = true;
805 mEnableExternal = true;
Marie Janssen59804562016-12-28 14:13:21 -0800806 sendEnableMsg(true, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800807 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700808 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700809 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700810
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700811 public boolean enable(String packageName) throws RemoteException {
812 final int callingUid = Binder.getCallingUid();
813 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
814
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100815 if (isBluetoothDisallowed()) {
816 if (DBG) {
817 Slog.d(TAG,"enable(): not enabling - bluetooth disallowed");
818 }
819 return false;
820 }
821
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700822 if (!callerSystem) {
823 if (!checkIfCallerIsForegroundUser()) {
824 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
825 return false;
826 }
827
828 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
829 "Need BLUETOOTH ADMIN permission");
830
831 if (!isEnabled() && mPermissionReviewRequired
832 && startConsentUiIfNeeded(packageName, callingUid,
833 BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
834 return false;
835 }
fredcf2458862012-04-16 15:18:27 -0700836 }
837
Zhihai Xu401202b2012-12-03 11:36:21 -0800838 if (DBG) {
Marie Janssen59804562016-12-28 14:13:21 -0800839 Slog.d(TAG,"enable(" + packageName + "): mBluetooth =" + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800840 " mBinding = " + mBinding + " mState = " +
841 BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700842 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800843
844 synchronized(mReceiver) {
845 mQuietEnableExternal = false;
846 mEnableExternal = true;
847 // waive WRITE_SECURE_SETTINGS permission check
Marie Janssen59804562016-12-28 14:13:21 -0800848 sendEnableMsg(false, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800849 }
Jeff Sharkey67609c72016-03-05 14:29:13 -0700850 if (DBG) Slog.d(TAG, "enable returning");
Zhihai Xu401202b2012-12-03 11:36:21 -0800851 return true;
fredc0f420372012-04-12 00:02:00 -0700852 }
853
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700854 public boolean disable(String packageName, boolean persist) throws RemoteException {
855 final int callingUid = Binder.getCallingUid();
856 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700857
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700858 if (!callerSystem) {
859 if (!checkIfCallerIsForegroundUser()) {
860 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
861 return false;
862 }
863
864 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
865 "Need BLUETOOTH ADMIN permission");
866
867 if (isEnabled() && mPermissionReviewRequired
868 && startConsentUiIfNeeded(packageName, callingUid,
869 BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
870 return false;
871 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700872 }
873
fredcf2458862012-04-16 15:18:27 -0700874 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700875 Slog.d(TAG,"disable(): mBluetooth = " + mBluetooth +
Matthew Xiecdce0b92012-07-12 19:06:15 -0700876 " mBinding = " + mBinding);
877 }
fredcf2458862012-04-16 15:18:27 -0700878
Zhihai Xu401202b2012-12-03 11:36:21 -0800879 synchronized(mReceiver) {
880 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800881 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800882 }
883 mEnableExternal = false;
Marie Janssen59804562016-12-28 14:13:21 -0800884 sendDisableMsg(packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800885 }
fredc0f420372012-04-12 00:02:00 -0700886 return true;
887 }
888
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700889 private boolean startConsentUiIfNeeded(String packageName,
890 int callingUid, String intentAction) throws RemoteException {
891 try {
892 // Validate the package only if we are going to use it
893 ApplicationInfo applicationInfo = mContext.getPackageManager()
894 .getApplicationInfoAsUser(packageName,
895 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
896 UserHandle.getUserId(callingUid));
897 if (applicationInfo.uid != callingUid) {
898 throw new SecurityException("Package " + callingUid
899 + " not in uid " + callingUid);
900 }
901
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000902 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000903 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
904 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
905 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
906 try {
907 mContext.startActivity(intent);
908 } catch (ActivityNotFoundException e) {
909 // Shouldn't happen
910 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
911 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700912 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000913 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700914 } catch (PackageManager.NameNotFoundException e) {
915 throw new RemoteException(e.getMessage());
916 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700917 }
918
fredc649fe492012-04-19 01:07:18 -0700919 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700920 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700921 Slog.d(TAG,"unbindAndFinish(): " + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800922 " mBinding = " + mBinding + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -0700923 }
924
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700925 try {
926 mBluetoothLock.writeLock().lock();
fredc0f420372012-04-12 00:02:00 -0700927 if (mUnbinding) return;
928 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -0700929 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -0700930 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -0700931 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -0800932 //Unregister callback object
933 try {
934 mBluetooth.unregisterCallback(mBluetoothCallback);
935 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700936 Slog.e(TAG, "Unable to unregister BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -0700937 }
Marie Janssen9db28eb2016-01-12 16:05:15 -0800938 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -0700939 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -0700940 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -0700941 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700942 mBinding = false;
fredcf2458862012-04-16 15:18:27 -0700943 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -0800944 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -0700945 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800946 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700947 } finally {
948 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700949 }
950 }
951
Matthew Xieddf7e472013-03-01 18:41:02 -0800952 public IBluetoothGatt getBluetoothGatt() {
953 // sync protection
954 return mBluetoothGatt;
955 }
956
Benjamin Franze8b98922014-11-12 15:57:54 +0000957 @Override
958 public boolean bindBluetoothProfileService(int bluetoothProfile,
959 IBluetoothProfileServiceConnection proxy) {
960 if (!mEnable) {
961 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700962 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile +
Benjamin Franze8b98922014-11-12 15:57:54 +0000963 ", while Bluetooth was disabled");
964 }
965 return false;
966 }
967 synchronized (mProfileServices) {
968 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
969 if (psc == null) {
970 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700971 Slog.d(TAG, "Creating new ProfileServiceConnections object for"
Benjamin Franze8b98922014-11-12 15:57:54 +0000972 + " profile: " + bluetoothProfile);
973 }
Benjamin Franz5b614592014-12-09 18:58:45 +0000974
975 if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
976
977 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +0000978 psc = new ProfileServiceConnections(intent);
Benjamin Franz5b614592014-12-09 18:58:45 +0000979 if (!psc.bindService()) return false;
980
Benjamin Franze8b98922014-11-12 15:57:54 +0000981 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +0000982 }
983 }
984
985 // Introducing a delay to give the client app time to prepare
986 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
987 addProxyMsg.arg1 = bluetoothProfile;
988 addProxyMsg.obj = proxy;
989 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
990 return true;
991 }
992
993 @Override
994 public void unbindBluetoothProfileService(int bluetoothProfile,
995 IBluetoothProfileServiceConnection proxy) {
996 synchronized (mProfileServices) {
997 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
998 if (psc == null) {
999 return;
1000 }
1001 psc.removeProxy(proxy);
1002 }
1003 }
1004
1005 private void unbindAllBluetoothProfileServices() {
1006 synchronized (mProfileServices) {
1007 for (Integer i : mProfileServices.keySet()) {
1008 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +00001009 try {
1010 mContext.unbindService(psc);
1011 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001012 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +00001013 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001014 psc.removeAllProxies();
1015 }
1016 mProfileServices.clear();
1017 }
1018 }
1019
1020 /**
Miao Chou658bf2f2015-06-26 17:14:35 -07001021 * Send enable message and set adapter name and address. Called when the boot phase becomes
1022 * PHASE_SYSTEM_SERVICES_READY.
1023 */
1024 public void handleOnBootPhase() {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001025 if (DBG) Slog.d(TAG, "Bluetooth boot completed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001026 UserManagerInternal userManagerInternal =
1027 LocalServices.getService(UserManagerInternal.class);
1028 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001029 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01001030 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001031 return;
1032 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001033 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001034 if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
Ajay Panicker467bc042017-02-22 12:23:15 -08001035 sendEnableMsg(mQuietEnableExternal, REASON_SYSTEM_BOOT);
Ajay Panickerbf796d82016-03-11 13:47:20 -08001036 } else if (!isNameAndAddressSet()) {
1037 if (DBG) Slog.d(TAG, "Getting adapter name and address");
Ajay Panicker4bb48302016-03-31 14:14:27 -07001038 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1039 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001040 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001041 }
1042
1043 /**
1044 * Called when switching to a different foreground user.
1045 */
1046 public void handleOnSwitchUser(int userHandle) {
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001047 if (DBG) Slog.d(TAG, "User " + userHandle + " switched");
1048 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1049 }
1050
1051 /**
1052 * Called when user is unlocked.
1053 */
1054 public void handleOnUnlockUser(int userHandle) {
1055 if (DBG) Slog.d(TAG, "User " + userHandle + " unlocked");
1056 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001057 }
1058
1059 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001060 * This class manages the clients connected to a given ProfileService
1061 * and maintains the connection with that service.
1062 */
1063 final private class ProfileServiceConnections implements ServiceConnection,
1064 IBinder.DeathRecipient {
1065 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
1066 new RemoteCallbackList <IBluetoothProfileServiceConnection>();
1067 IBinder mService;
1068 ComponentName mClassName;
1069 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001070 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001071
1072 ProfileServiceConnections(Intent intent) {
1073 mService = null;
1074 mClassName = null;
1075 mIntent = intent;
1076 }
1077
Benjamin Franz5b614592014-12-09 18:58:45 +00001078 private boolean bindService() {
1079 if (mIntent != null && mService == null &&
1080 doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001081 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1082 msg.obj = this;
1083 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001084 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001085 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001086 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001087 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001088 }
1089
1090 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1091 mProxies.register(proxy);
1092 if (mService != null) {
1093 try{
1094 proxy.onServiceConnected(mClassName, mService);
1095 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001096 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001097 }
1098 } else {
1099 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1100 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1101 msg.obj = this;
1102 mHandler.sendMessage(msg);
1103 }
1104 }
1105 }
1106
1107 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1108 if (proxy != null) {
1109 if (mProxies.unregister(proxy)) {
1110 try {
1111 proxy.onServiceDisconnected(mClassName);
1112 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001113 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001114 }
1115 }
1116 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001117 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001118 }
1119 }
1120
1121 private void removeAllProxies() {
1122 onServiceDisconnected(mClassName);
1123 mProxies.kill();
1124 }
1125
1126 @Override
1127 public void onServiceConnected(ComponentName className, IBinder service) {
1128 // remove timeout message
1129 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1130 mService = service;
1131 mClassName = className;
1132 try {
1133 mService.linkToDeath(this, 0);
1134 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001135 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001136 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001137
1138 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001139 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001140 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001141 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001142 mInvokingProxyCallbacks = true;
1143
1144 final int n = mProxies.beginBroadcast();
1145 try {
1146 for (int i = 0; i < n; i++) {
1147 try {
1148 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1149 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001150 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001151 }
1152 }
1153 } finally {
1154 mProxies.finishBroadcast();
1155 mInvokingProxyCallbacks = false;
1156 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001157 }
1158
1159 @Override
1160 public void onServiceDisconnected(ComponentName className) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001161 if (mService == null) return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001162 mService.unlinkToDeath(this, 0);
1163 mService = null;
1164 mClassName = null;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001165
1166 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001167 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001168 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001169 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001170 mInvokingProxyCallbacks = true;
1171
1172 final int n = mProxies.beginBroadcast();
1173 try {
1174 for (int i = 0; i < n; i++) {
1175 try {
1176 mProxies.getBroadcastItem(i).onServiceDisconnected(className);
1177 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001178 Slog.e(TAG, "Unable to disconnect from proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001179 }
1180 }
1181 } finally {
1182 mProxies.finishBroadcast();
1183 mInvokingProxyCallbacks = false;
1184 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001185 }
1186
1187 @Override
1188 public void binderDied() {
1189 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001190 Slog.w(TAG, "Profile service for profile: " + mClassName
Benjamin Franze8b98922014-11-12 15:57:54 +00001191 + " died.");
1192 }
1193 onServiceDisconnected(mClassName);
1194 // Trigger rebind
1195 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1196 msg.obj = this;
1197 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1198 }
1199 }
1200
fredcbf072a72012-05-09 16:52:50 -07001201 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001202 try {
1203 int n = mStateChangeCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001204 if (DBG) Slog.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001205 for (int i=0; i <n;i++) {
1206 try {
1207 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1208 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001209 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001210 }
fredcbf072a72012-05-09 16:52:50 -07001211 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001212 } finally {
1213 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001214 }
fredcbf072a72012-05-09 16:52:50 -07001215 }
1216
1217 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001218 * Inform BluetoothAdapter instances that Adapter service is up
1219 */
1220 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001221 try {
1222 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001223 Slog.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001224 for (int i=0; i <n;i++) {
1225 try {
1226 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
1227 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001228 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001229 }
1230 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001231 } finally {
1232 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001233 }
1234 }
1235 /**
fredcbf072a72012-05-09 16:52:50 -07001236 * Inform BluetoothAdapter instances that Adapter service is down
1237 */
1238 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001239 try {
1240 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001241 Slog.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001242 for (int i=0; i <n;i++) {
1243 try {
1244 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
1245 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001246 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001247 }
1248 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001249 } finally {
1250 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001251 }
1252 }
Svet Ganov408abf72015-05-12 19:13:36 -07001253
fredc0f420372012-04-12 00:02:00 -07001254 public String getAddress() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001255 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
Svet Ganov408abf72015-05-12 19:13:36 -07001256 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001257
Zhihai Xu6eb76522012-11-29 15:41:04 -08001258 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
Svet Ganov408abf72015-05-12 19:13:36 -07001259 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001260 Slog.w(TAG,"getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001261 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001262 }
1263
Svet Ganov408abf72015-05-12 19:13:36 -07001264 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1265 != PackageManager.PERMISSION_GRANTED) {
1266 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1267 }
1268
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001269 try {
1270 mBluetoothLock.readLock().lock();
1271 if (mBluetooth != null) return mBluetooth.getAddress();
1272 } catch (RemoteException e) {
1273 Slog.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e);
1274 } finally {
1275 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001276 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001277
Matthew Xiecdce0b92012-07-12 19:06:15 -07001278 // mAddress is accessed from outside.
1279 // It is alright without a lock. Here, bluetooth is off, no other thread is
1280 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001281 return mAddress;
1282 }
fredc649fe492012-04-19 01:07:18 -07001283
fredc0f420372012-04-12 00:02:00 -07001284 public String getName() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001285 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
1286 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001287
Zhihai Xu6eb76522012-11-29 15:41:04 -08001288 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
1289 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001290 Slog.w(TAG,"getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001291 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001292 }
1293
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001294 try {
1295 mBluetoothLock.readLock().lock();
1296 if (mBluetooth != null) return mBluetooth.getName();
1297 } catch (RemoteException e) {
1298 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1299 } finally {
1300 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001301 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001302
Matthew Xiecdce0b92012-07-12 19:06:15 -07001303 // mName is accessed from outside.
1304 // It alright without a lock. Here, bluetooth is off, no other thread is
1305 // changing mName
fredc0f420372012-04-12 00:02:00 -07001306 return mName;
1307 }
1308
fredc0f420372012-04-12 00:02:00 -07001309 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001310 public void onServiceConnected(ComponentName componentName, IBinder service) {
1311 String name = componentName.getClassName();
1312 if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
fredc0f420372012-04-12 00:02:00 -07001313 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001314 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001315 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001316 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001317 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1318 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001319 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001320 return;
1321 }
fredc0f420372012-04-12 00:02:00 -07001322 msg.obj = service;
1323 mHandler.sendMessage(msg);
1324 }
1325
Marie Janssencb21ad72016-12-13 10:51:02 -08001326 public void onServiceDisconnected(ComponentName componentName) {
1327 // Called if we unexpectedly disconnect.
1328 String name = componentName.getClassName();
1329 if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
fredc0f420372012-04-12 00:02:00 -07001330 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001331 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001332 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001333 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001334 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1335 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001336 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001337 return;
1338 }
fredc0f420372012-04-12 00:02:00 -07001339 mHandler.sendMessage(msg);
1340 }
1341 }
1342
1343 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1344
Zhihai Xu40874a02012-10-08 17:57:03 -07001345 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001346 boolean mGetNameAddressOnly = false;
1347
Zhihai Xu40874a02012-10-08 17:57:03 -07001348 public BluetoothHandler(Looper looper) {
1349 super(looper);
1350 }
1351
fredc0f420372012-04-12 00:02:00 -07001352 @Override
1353 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001354 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001355 case MESSAGE_GET_NAME_AND_ADDRESS:
1356 if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001357 try {
1358 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001359 if ((mBluetooth == null) && (!mBinding)) {
1360 if (DBG) Slog.d(TAG, "Binding to service to get name and address");
1361 mGetNameAddressOnly = true;
1362 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1363 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1364 Intent i = new Intent(IBluetooth.class.getName());
1365 if (!doBind(i, mConnection,
1366 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1367 UserHandle.CURRENT)) {
1368 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1369 } else {
1370 mBinding = true;
1371 }
1372 } else if (mBluetooth != null) {
1373 try {
1374 storeNameAndAddress(mBluetooth.getName(),
1375 mBluetooth.getAddress());
1376 } catch (RemoteException re) {
1377 Slog.e(TAG, "Unable to grab names", re);
1378 }
1379 if (mGetNameAddressOnly && !mEnable) {
1380 unbindAndFinish();
1381 }
1382 mGetNameAddressOnly = false;
1383 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001384 } finally {
1385 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001386 }
1387 break;
1388
Matthew Xiecdce0b92012-07-12 19:06:15 -07001389 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001390 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001391 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001392 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001393 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1394 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001395
1396 // Use service interface to get the exact state
1397 try {
1398 mBluetoothLock.readLock().lock();
1399 if (mBluetooth != null) {
1400 int state = mBluetooth.getState();
1401 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001402 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001403 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001404 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001405 break;
1406 }
1407 }
1408 } catch (RemoteException e) {
1409 Slog.e(TAG, "", e);
1410 } finally {
1411 mBluetoothLock.readLock().unlock();
1412 }
1413
1414 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001415 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001416 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001417 } else {
1418 //
1419 // We need to wait until transitioned to STATE_OFF and
1420 // the previous Bluetooth process has exited. The
1421 // waiting period has three components:
1422 // (a) Wait until the local state is STATE_OFF. This
1423 // is accomplished by "waitForOnOff(false, true)".
1424 // (b) Wait until the STATE_OFF state is updated to
1425 // all components.
1426 // (c) Wait until the Bluetooth process exits, and
1427 // ActivityManager detects it.
1428 // The waiting for (b) and (c) is accomplished by
1429 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1430 // message. On slower devices, that delay needs to be
1431 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1432 //
1433 waitForOnOff(false, true);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001434 Message restartMsg = mHandler.obtainMessage(
1435 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1436 mHandler.sendMessageDelayed(restartMsg,
1437 2 * SERVICE_RESTART_TIME_MS);
1438 }
fredc649fe492012-04-19 01:07:18 -07001439 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001440
fredc0f420372012-04-12 00:02:00 -07001441 case MESSAGE_DISABLE:
Marie Janssencb21ad72016-12-13 10:51:02 -08001442 if (DBG) Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
Zhihai Xu40874a02012-10-08 17:57:03 -07001443 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1444 if (mEnable && mBluetooth != null) {
1445 waitForOnOff(true, false);
1446 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001447 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001448 waitForOnOff(false, false);
1449 } else {
1450 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001451 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001452 }
fredc0f420372012-04-12 00:02:00 -07001453 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001454
Stanley Tng873b5702017-05-01 21:27:31 -07001455 case MESSAGE_RESTORE_USER_SETTING:
1456 try {
1457 if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
1458 if (DBG) Slog.d(TAG, "Restore Bluetooth state to disabled");
1459 disable(REASON_RESTORE_USER_SETTING, true);
1460 } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
1461 if (DBG) Slog.d(TAG, "Restore Bluetooth state to enabled");
1462 enable(REASON_RESTORE_USER_SETTING);
1463 }
1464 } catch (RemoteException e) {
1465 Slog.e(TAG,"Unable to change Bluetooth On setting", e);
1466 }
1467 break;
1468
fredc0f420372012-04-12 00:02:00 -07001469 case MESSAGE_REGISTER_ADAPTER:
1470 {
1471 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001472 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001473 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001474 }
fredc0f420372012-04-12 00:02:00 -07001475 case MESSAGE_UNREGISTER_ADAPTER:
1476 {
1477 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001478 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001479 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001480 }
fredc0f420372012-04-12 00:02:00 -07001481 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
1482 {
1483 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001484 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001485 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001486 }
fredc0f420372012-04-12 00:02:00 -07001487 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK:
1488 {
1489 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001490 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001491 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001492 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001493 case MESSAGE_ADD_PROXY_DELAYED:
1494 {
1495 ProfileServiceConnections psc = mProfileServices.get(
1496 new Integer(msg.arg1));
1497 if (psc == null) {
1498 break;
1499 }
1500 IBluetoothProfileServiceConnection proxy =
1501 (IBluetoothProfileServiceConnection) msg.obj;
1502 psc.addProxy(proxy);
1503 break;
1504 }
1505 case MESSAGE_BIND_PROFILE_SERVICE:
1506 {
1507 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1508 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1509 if (psc == null) {
1510 break;
1511 }
1512 psc.bindService();
1513 break;
1514 }
fredc0f420372012-04-12 00:02:00 -07001515 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
1516 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001517 if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
fredc0f420372012-04-12 00:02:00 -07001518
1519 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001520 try {
1521 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001522 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001523 mBluetoothGatt = IBluetoothGatt.Stub
1524 .asInterface(Binder.allowBlocking(service));
Nitin Arorad055adb2015-03-02 15:03:51 -08001525 onBluetoothGattServiceUp();
Matthew Xieddf7e472013-03-01 18:41:02 -08001526 break;
1527 } // else must be SERVICE_IBLUETOOTH
1528
1529 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001530 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001531
fredc0f420372012-04-12 00:02:00 -07001532 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001533 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001534 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001535
Ajay Panicker4bb48302016-03-31 14:14:27 -07001536 if (!isNameAndAddressSet()) {
1537 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1538 mHandler.sendMessage(getMsg);
1539 if (mGetNameAddressOnly) return;
1540 }
1541
Matthew Xiecdce0b92012-07-12 19:06:15 -07001542 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001543 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001544 mBluetooth.registerCallback(mBluetoothCallback);
1545 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001546 Slog.e(TAG, "Unable to register BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -07001547 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001548 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001549 sendBluetoothServiceUpCallback();
1550
Matthew Xiecdce0b92012-07-12 19:06:15 -07001551 //Do enable request
1552 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001553 if (mQuietEnable == false) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001554 if (!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001555 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001556 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001557 } else {
1558 if (!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001559 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001560 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001561 }
1562 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001563 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001564 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001565 } finally {
1566 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001567 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001568
1569 if (!mEnable) {
1570 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001571 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001572 waitForOnOff(false, false);
1573 }
fredc649fe492012-04-19 01:07:18 -07001574 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001575 }
fredcbf072a72012-05-09 16:52:50 -07001576 case MESSAGE_BLUETOOTH_STATE_CHANGE:
fredc0f420372012-04-12 00:02:00 -07001577 {
fredcbf072a72012-05-09 16:52:50 -07001578 int prevState = msg.arg1;
1579 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001580 if (DBG) {
1581 Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(prevState) + " > " +
1582 BluetoothAdapter.nameForState(newState));
1583 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001584 mState = newState;
1585 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001586 // handle error state transition case from TURNING_ON to OFF
1587 // unbind and rebind bluetooth service and enable bluetooth
Nitin Arorad055adb2015-03-02 15:03:51 -08001588 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001589 (newState == BluetoothAdapter.STATE_OFF) &&
1590 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001591 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001592 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001593 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001594 (newState == BluetoothAdapter.STATE_BLE_ON) &&
1595 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001596 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001597 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001598 // If we tried to enable BT while BT was in the process of shutting down,
1599 // wait for the BT process to fully tear down and then force a restart
1600 // here. This is a bit of a hack (b/29363429).
1601 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) &&
1602 (newState == BluetoothAdapter.STATE_OFF)) {
1603 if (mEnable) {
1604 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1605 waitForOnOff(false, true);
1606 Message restartMsg = mHandler.obtainMessage(
1607 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1608 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1609 }
1610 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001611 if (newState == BluetoothAdapter.STATE_ON ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001612 newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001613 // bluetooth is working, reset the counter
1614 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001615 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001616 mErrorRecoveryRetryCounter = 0;
1617 }
1618 }
fredc649fe492012-04-19 01:07:18 -07001619 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001620 }
fredc0f420372012-04-12 00:02:00 -07001621 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
1622 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001623 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001624 try {
1625 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001626 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1627 // if service is unbinded already, do nothing and return
1628 if (mBluetooth == null) break;
1629 mBluetooth = null;
1630 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1631 mBluetoothGatt = null;
1632 break;
1633 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001634 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001635 break;
1636 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001637 } finally {
1638 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301639 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001640
Marie Janssene54b4222017-03-16 18:10:59 -07001641 // log the unexpected crash
1642 addCrashLog();
1643 addActiveLog(REASON_UNEXPECTED, false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001644 if (mEnable) {
1645 mEnable = false;
1646 // Send a Bluetooth Restart message
1647 Message restartMsg = mHandler.obtainMessage(
1648 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1649 mHandler.sendMessageDelayed(restartMsg,
1650 SERVICE_RESTART_TIME_MS);
1651 }
1652
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001653 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001654
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001655 // Send BT state broadcast to update
1656 // the BT icon correctly
1657 if ((mState == BluetoothAdapter.STATE_TURNING_ON) ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001658 (mState == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001659 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1660 BluetoothAdapter.STATE_TURNING_OFF);
1661 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001662 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001663 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1664 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
1665 BluetoothAdapter.STATE_OFF);
1666 }
1667
1668 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1669 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001670 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001671 }
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301672 case MESSAGE_RESTART_BLUETOOTH_SERVICE:
1673 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001674 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301675 /* Enable without persisting the setting as
1676 it doesnt change when IBluetooth
1677 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001678 mEnable = true;
Marie Janssene54b4222017-03-16 18:10:59 -07001679 addActiveLog(REASON_RESTARTED, true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001680 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301681 break;
1682 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001683 case MESSAGE_TIMEOUT_BIND: {
1684 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1685 mBluetoothLock.writeLock().lock();
1686 mBinding = false;
1687 mBluetoothLock.writeLock().unlock();
1688 break;
1689 }
fredc0f420372012-04-12 00:02:00 -07001690 case MESSAGE_TIMEOUT_UNBIND:
1691 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001692 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001693 mBluetoothLock.writeLock().lock();
1694 mUnbinding = false;
1695 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001696 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001697 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001698
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001699 case MESSAGE_USER_SWITCHED: {
1700 if (DBG) Slog.d(TAG, "MESSAGE_USER_SWITCHED");
Zhihai Xu40874a02012-10-08 17:57:03 -07001701 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001702
Zhihai Xu40874a02012-10-08 17:57:03 -07001703 /* disable and enable BT when detect a user switch */
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001704 if (mBluetooth != null && isEnabled()) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001705 try {
1706 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001707 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001708 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001709 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001710 } catch (RemoteException re) {
1711 Slog.e(TAG, "Unable to unregister", re);
1712 } finally {
1713 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001714 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001715
1716 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1717 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1718 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1719 mState = BluetoothAdapter.STATE_OFF;
1720 }
1721 if (mState == BluetoothAdapter.STATE_OFF) {
1722 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1723 mState = BluetoothAdapter.STATE_TURNING_ON;
1724 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001725
1726 waitForOnOff(true, false);
1727
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001728 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1729 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1730 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001731
Benjamin Franze8b98922014-11-12 15:57:54 +00001732 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001733 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07001734 addActiveLog(REASON_USER_SWITCH, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001735 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001736 // Pbap service need receive STATE_TURNING_OFF intent to close
1737 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1738 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001739
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001740 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001741
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001742 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Zhihai Xu40874a02012-10-08 17:57:03 -07001743 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001744 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001745
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001746 try {
1747 mBluetoothLock.writeLock().lock();
1748 if (mBluetooth != null) {
1749 mBluetooth = null;
1750 // Unbind
1751 mContext.unbindService(mConnection);
1752 }
1753 mBluetoothGatt = null;
1754 } finally {
1755 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001756 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001757
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001758 //
1759 // If disabling Bluetooth times out, wait for an
1760 // additional amount of time to ensure the process is
1761 // shut down completely before attempting to restart.
1762 //
1763 if (didDisableTimeout) {
1764 SystemClock.sleep(3000);
1765 } else {
1766 SystemClock.sleep(100);
1767 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001768
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001769 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1770 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001771 // enable
Marie Janssene54b4222017-03-16 18:10:59 -07001772 addActiveLog(REASON_USER_SWITCH, true);
Ram Periathiruvadi88256d12017-05-03 19:11:20 -07001773 // mEnable flag could have been reset on disableBLE. Reenable it.
1774 mEnable = true;
Zhihai Xu401202b2012-12-03 11:36:21 -08001775 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001776 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001777 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1778 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001779 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001780 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1781 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001782 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001783 }
John Spurlock8a985d22014-02-25 09:40:05 -05001784 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001785 break;
1786 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001787 case MESSAGE_USER_UNLOCKED: {
1788 if (DBG) Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1789 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1790
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001791 if (mEnable && !mBinding && (mBluetooth == null)) {
1792 // We should be connected, but we gave up for some
1793 // reason; maybe the Bluetooth service wasn't encryption
1794 // aware, so try binding again.
1795 if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1796 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001797 }
1798 }
fredc0f420372012-04-12 00:02:00 -07001799 }
1800 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001801 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001802
Zhihai Xu401202b2012-12-03 11:36:21 -08001803 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001804 mQuietEnable = quietMode;
1805
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001806 try {
1807 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001808 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001809 //Start bind timeout and bind
1810 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1811 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001812 Intent i = new Intent(IBluetooth.class.getName());
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001813 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1814 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001815 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001816 } else {
1817 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001818 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001819 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001820 //Enable bluetooth
1821 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001822 if (!mQuietEnable) {
1823 if(!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001824 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001825 }
1826 }
1827 else {
1828 if(!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001829 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001830 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001831 }
1832 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001833 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001834 }
1835 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001836 } finally {
1837 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001838 }
1839 }
1840
Dianne Hackborn221ea892013-08-04 16:50:16 -07001841 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1842 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1843 intent.setComponent(comp);
1844 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001845 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001846 return false;
1847 }
1848 return true;
1849 }
1850
Zhihai Xu401202b2012-12-03 11:36:21 -08001851 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001852 try {
1853 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001854 if (mBluetooth != null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001855 if (DBG) Slog.d(TAG,"Sending off request.");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001856 if (!mBluetooth.disable()) {
1857 Slog.e(TAG,"IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001858 }
1859 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001860 } catch (RemoteException e) {
1861 Slog.e(TAG,"Unable to call disable()",e);
1862 } finally {
1863 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001864 }
1865 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001866
1867 private boolean checkIfCallerIsForegroundUser() {
1868 int foregroundUser;
1869 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001870 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07001871 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00001872 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1873 UserInfo ui = um.getProfileParent(callingUser);
1874 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001875 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07001876 boolean valid = false;
1877 try {
1878 foregroundUser = ActivityManager.getCurrentUser();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001879 valid = (callingUser == foregroundUser) ||
Benjamin Franze8b98922014-11-12 15:57:54 +00001880 parentUser == foregroundUser ||
Adrian Roosbd9a9a52014-08-18 15:31:57 +02001881 callingAppId == Process.NFC_UID ||
1882 callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08001883 if (DBG && !valid) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001884 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid
Zhihai Xu40874a02012-10-08 17:57:03 -07001885 + " callingUser=" + callingUser
Benjamin Franze8b98922014-11-12 15:57:54 +00001886 + " parentUser=" + parentUser
Zhihai Xu40874a02012-10-08 17:57:03 -07001887 + " foregroundUser=" + foregroundUser);
1888 }
1889 } finally {
1890 Binder.restoreCallingIdentity(callingIdentity);
1891 }
1892 return valid;
1893 }
1894
Nitin Arorad055adb2015-03-02 15:03:51 -08001895 private void sendBleStateChanged(int prevState, int newState) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001896 if (DBG) Slog.d(TAG,"Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) +
1897 " > " + BluetoothAdapter.nameForState(newState));
Nitin Arorad055adb2015-03-02 15:03:51 -08001898 // Send broadcast message to everyone else
1899 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
1900 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1901 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1902 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1903 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
1904 }
1905
Zhihai Xu40874a02012-10-08 17:57:03 -07001906 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001907 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08001908 if (prevState == newState) { // No change. Nothing to do.
1909 return;
1910 }
1911 // Notify all proxy objects first of adapter state change
1912 if (newState == BluetoothAdapter.STATE_BLE_ON ||
1913 newState == BluetoothAdapter.STATE_OFF) {
1914 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
1915 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07001916
Marie Janssencb21ad72016-12-13 10:51:02 -08001917 if (newState == BluetoothAdapter.STATE_OFF) {
1918 // If Bluetooth is off, send service down event to proxy objects, and unbind
1919 if (DBG) Slog.d(TAG, "Bluetooth is complete send Service Down");
1920 sendBluetoothServiceDownCallback();
1921 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08001922 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08001923 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08001924 isStandardBroadcast = false;
1925
Marie Janssencb21ad72016-12-13 10:51:02 -08001926 } else if (!intermediate_off) {
1927 // connect to GattService
1928 if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode");
1929 if (mBluetoothGatt != null) {
1930 if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp");
1931 onBluetoothGattServiceUp();
1932 } else {
1933 if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service");
1934 if (mContext.getPackageManager().hasSystemFeature(
1935 PackageManager.FEATURE_BLUETOOTH_LE)) {
1936 Intent i = new Intent(IBluetoothGatt.class.getName());
1937 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT);
1938 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001939 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001940 sendBleStateChanged(prevState, newState);
1941 //Don't broadcase this as std intent
1942 isStandardBroadcast = false;
1943
1944 } else if (intermediate_off) {
1945 if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode");
1946 // For LE only mode, broadcast as is
1947 sendBleStateChanged(prevState, newState);
1948 sendBluetoothStateCallback(false); // BT is OFF for general users
1949 // Broadcast as STATE_OFF
1950 newState = BluetoothAdapter.STATE_OFF;
1951 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08001952 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001953 } else if (newState == BluetoothAdapter.STATE_ON) {
1954 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
1955 sendBluetoothStateCallback(isUp);
1956 sendBleStateChanged(prevState, newState);
1957
1958 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON ||
1959 newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) {
1960 sendBleStateChanged(prevState, newState);
1961 isStandardBroadcast = false;
1962
1963 } else if (newState == BluetoothAdapter.STATE_TURNING_ON ||
1964 newState == BluetoothAdapter.STATE_TURNING_OFF) {
1965 sendBleStateChanged(prevState, newState);
1966 }
1967
1968 if (isStandardBroadcast) {
1969 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
1970 // Show prevState of BLE_ON as OFF to standard users
1971 prevState = BluetoothAdapter.STATE_OFF;
1972 }
1973 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
1974 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1975 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1976 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1977 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07001978 }
1979 }
1980
1981 /**
1982 * if on is true, wait for state become ON
1983 * if off is true, wait for state become OFF
1984 * if both on and off are false, wait for state not ON
1985 */
1986 private boolean waitForOnOff(boolean on, boolean off) {
1987 int i = 0;
1988 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001989 try {
1990 mBluetoothLock.readLock().lock();
1991 if (mBluetooth == null) break;
1992 if (on) {
1993 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true;
1994 } else if (off) {
1995 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true;
1996 } else {
1997 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true;
Zhihai Xu40874a02012-10-08 17:57:03 -07001998 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001999 } catch (RemoteException e) {
2000 Slog.e(TAG, "getState()", e);
2001 break;
2002 } finally {
2003 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07002004 }
2005 if (on || off) {
2006 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002007 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07002008 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07002009 }
Zhihai Xu40874a02012-10-08 17:57:03 -07002010 i++;
2011 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07002012 Slog.e(TAG,"waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07002013 return false;
2014 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08002015
Marie Janssen59804562016-12-28 14:13:21 -08002016 private void sendDisableMsg(String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002017 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Marie Janssen59804562016-12-28 14:13:21 -08002018 addActiveLog(packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08002019 }
2020
Marie Janssen59804562016-12-28 14:13:21 -08002021 private void sendEnableMsg(boolean quietMode, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08002022 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
2023 quietMode ? 1 : 0, 0));
Marie Janssen59804562016-12-28 14:13:21 -08002024 addActiveLog(packageName, true);
Marie Janssen12a35012017-06-26 07:21:03 -07002025 mLastEnabledTime = SystemClock.elapsedRealtime();
Marie Janssen59804562016-12-28 14:13:21 -08002026 }
2027
2028 private void addActiveLog(String packageName, boolean enable) {
2029 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07002030 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08002031 mActiveLogs.remove();
2032 }
2033 mActiveLogs.add(new ActiveLog(packageName, enable, System.currentTimeMillis()));
2034 }
Zhihai Xu401202b2012-12-03 11:36:21 -08002035 }
2036
Marie Janssene54b4222017-03-16 18:10:59 -07002037 private void addCrashLog() {
2038 synchronized (mCrashTimestamps) {
2039 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) mCrashTimestamps.removeFirst();
2040 mCrashTimestamps.add(System.currentTimeMillis());
2041 mCrashes++;
2042 }
2043 }
2044
Marie Janssen2977c3e2016-11-09 12:01:24 -08002045 private void recoverBluetoothServiceFromError(boolean clearBle) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07002046 Slog.e(TAG,"recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002047 try {
2048 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002049 if (mBluetooth != null) {
2050 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002051 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002052 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002053 } catch (RemoteException re) {
2054 Slog.e(TAG, "Unable to unregister", re);
2055 } finally {
2056 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002057 }
2058
2059 SystemClock.sleep(500);
2060
2061 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07002062 addActiveLog(REASON_START_CRASH, false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002063 handleDisable();
2064
2065 waitForOnOff(false, true);
2066
2067 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002068
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002069 try {
2070 mBluetoothLock.writeLock().lock();
2071 if (mBluetooth != null) {
2072 mBluetooth = null;
2073 // Unbind
2074 mContext.unbindService(mConnection);
2075 }
2076 mBluetoothGatt = null;
2077 } finally {
2078 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002079 }
2080
2081 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2082 mState = BluetoothAdapter.STATE_OFF;
2083
Marie Janssen2977c3e2016-11-09 12:01:24 -08002084 if (clearBle) {
2085 clearBleApps();
2086 }
2087
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002088 mEnable = false;
2089
2090 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2091 // Send a Bluetooth Restart message to reenable bluetooth
2092 Message restartMsg = mHandler.obtainMessage(
2093 MESSAGE_RESTART_BLUETOOTH_SERVICE);
2094 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2095 } else {
2096 // todo: notify user to power down and power up phone to make bluetooth work.
2097 }
2098 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002099
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002100 private boolean isBluetoothDisallowed() {
2101 long callingIdentity = Binder.clearCallingIdentity();
2102 try {
2103 return mContext.getSystemService(UserManager.class)
2104 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2105 } finally {
2106 Binder.restoreCallingIdentity(callingIdentity);
2107 }
2108 }
2109
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002110 /**
2111 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002112 * offered to the user if Bluetooth or sharing is disallowed. Puts the component to its default
2113 * state if Bluetooth is not disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002114 *
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002115 * @param userId user to disable bluetooth sharing for.
2116 * @param bluetoothSharingDisallowed whether bluetooth sharing is disallowed.
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002117 */
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002118 private void updateOppLauncherComponentState(int userId, boolean bluetoothSharingDisallowed) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002119 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2120 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002121 final int newState = bluetoothSharingDisallowed
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002122 ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2123 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2124 try {
Pavel Grafov4f4f6f82017-03-28 13:44:04 +01002125 final IPackageManager imp = AppGlobals.getPackageManager();
Myles Watson6291fae2017-06-29 03:12:02 -07002126 imp.setComponentEnabledSetting(oppLauncherComponent, newState,
2127 PackageManager.DONT_KILL_APP, userId);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002128 } catch (Exception e) {
2129 // The component was not found, do nothing.
2130 }
2131 }
2132
Mike Lockwood726d4de2014-10-28 14:06:28 -07002133 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002134 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002135 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002136 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002137
2138 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2139
2140 if (!protoOut) {
2141 writer.println("Bluetooth Status");
2142 writer.println(" enabled: " + isEnabled());
2143 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2144 writer.println(" address: " + mAddress);
2145 writer.println(" name: " + mName);
2146 if (mEnable) {
Marie Janssen12a35012017-06-26 07:21:03 -07002147 long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
Marie Janssen59804562016-12-28 14:13:21 -08002148 String onDurationString = String.format("%02d:%02d:%02d.%03d",
2149 (int)(onDuration / (1000 * 60 * 60)),
2150 (int)((onDuration / (1000 * 60)) % 60),
2151 (int)((onDuration / 1000) % 60),
2152 (int)(onDuration % 1000));
Andre Eisenbache66e1682017-04-10 13:49:13 -07002153 writer.println(" time since enabled: " + onDurationString);
Marie Janssen59804562016-12-28 14:13:21 -08002154 }
2155
Marie Janssena95924d2017-01-18 09:37:52 -08002156 if (mActiveLogs.size() == 0) {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002157 writer.println("\nBluetooth never enabled!");
Marie Janssena95924d2017-01-18 09:37:52 -08002158 } else {
Andre Eisenbache66e1682017-04-10 13:49:13 -07002159 writer.println("\nEnable log:");
Marie Janssena95924d2017-01-18 09:37:52 -08002160 for (ActiveLog log : mActiveLogs) {
2161 writer.println(" " + log);
2162 }
Marie Janssen59804562016-12-28 14:13:21 -08002163 }
2164
Andre Eisenbache66e1682017-04-10 13:49:13 -07002165 writer.println("\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
Marie Janssene54b4222017-03-16 18:10:59 -07002166 if (mCrashes == CRASH_LOG_MAX_SIZE) writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2167 for (Long time : mCrashTimestamps) {
2168 writer.println(" " + timeToLog(time.longValue()));
2169 }
2170
Andre Eisenbache66e1682017-04-10 13:49:13 -07002171 writer.println("\n" + mBleApps.size() + " BLE app" +
2172 (mBleApps.size() == 1 ? "" : "s") + "registered");
Marie Janssen59804562016-12-28 14:13:21 -08002173 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002174 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002175 }
2176
Marie Janssena95924d2017-01-18 09:37:52 -08002177 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002178 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002179 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002180 // Add arg to produce output
2181 args = new String[1];
2182 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002183 }
Marie Janssen59804562016-12-28 14:13:21 -08002184 }
2185
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002186 if (mBluetoothBinder == null) {
2187 errorMsg = "Bluetooth Service not connected";
2188 } else {
2189 try {
2190 mBluetoothBinder.dump(fd, args);
2191 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002192 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002193 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002194 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002195 if (errorMsg != null) {
2196 // Silently return if we are extracting metrics in Protobuf format
Marie Janssen59804562016-12-28 14:13:21 -08002197 if (protoOut) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002198 writer.println(errorMsg);
2199 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002200 }
fredc0f420372012-04-12 00:02:00 -07002201}