blob: 6c18b260e18db871f5a9ac2cc4b40619fb1a0f51 [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;
fredc0f420372012-04-12 00:02:00 -070021import android.bluetooth.BluetoothAdapter;
Benjamin Franze8b98922014-11-12 15:57:54 +000022import android.bluetooth.BluetoothProfile;
fredc0f420372012-04-12 00:02:00 -070023import android.bluetooth.IBluetooth;
fredcbf072a72012-05-09 16:52:50 -070024import android.bluetooth.IBluetoothCallback;
Wei Wange4a744b2015-06-11 17:50:29 -070025import android.bluetooth.IBluetoothGatt;
Benjamin Franze8b98922014-11-12 15:57:54 +000026import android.bluetooth.IBluetoothHeadset;
fredc0f420372012-04-12 00:02:00 -070027import android.bluetooth.IBluetoothManager;
28import android.bluetooth.IBluetoothManagerCallback;
Benjamin Franze8b98922014-11-12 15:57:54 +000029import android.bluetooth.IBluetoothProfileServiceConnection;
fredc0f420372012-04-12 00:02:00 -070030import android.bluetooth.IBluetoothStateChangeCallback;
Svet Ganov77df6f32016-08-17 11:46:34 -070031import android.content.ActivityNotFoundException;
fredc0f420372012-04-12 00:02:00 -070032import android.content.BroadcastReceiver;
33import android.content.ComponentName;
34import android.content.ContentResolver;
35import android.content.Context;
36import android.content.Intent;
37import android.content.IntentFilter;
38import android.content.ServiceConnection;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070039import android.content.pm.ApplicationInfo;
Matthew Xie32ab77b2013-05-08 19:26:57 -070040import android.content.pm.PackageManager;
Benjamin Franze8b98922014-11-12 15:57:54 +000041import android.content.pm.UserInfo;
Wei Wange4a744b2015-06-11 17:50:29 -070042import android.database.ContentObserver;
Zhihai Xu40874a02012-10-08 17:57:03 -070043import android.os.Binder;
Svetoslav Ganovac69be52016-06-29 17:31:44 -070044import android.os.Build;
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +010045import android.os.Bundle;
fredc0f420372012-04-12 00:02:00 -070046import android.os.Handler;
fredc0f420372012-04-12 00:02:00 -070047import android.os.IBinder;
Zhihai Xu40874a02012-10-08 17:57:03 -070048import android.os.Looper;
fredc0f420372012-04-12 00:02:00 -070049import android.os.Message;
Zhihai Xu40874a02012-10-08 17:57:03 -070050import android.os.Process;
fredcd6883532012-04-25 17:46:13 -070051import android.os.RemoteCallbackList;
fredc0f420372012-04-12 00:02:00 -070052import android.os.RemoteException;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010053import android.os.ServiceManager;
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;
Lenka Trochtovac6f0e232017-01-17 10:35:49 +010064import com.android.server.pm.PackageManagerService;
65
Mike Lockwood726d4de2014-10-28 14:06:28 -070066import java.io.FileDescriptor;
67import java.io.PrintWriter;
Marie Janssen2977c3e2016-11-09 12:01:24 -080068import java.util.concurrent.ConcurrentHashMap;
Marie Janssen59804562016-12-28 14:13:21 -080069import java.util.concurrent.locks.ReentrantReadWriteLock;
Benjamin Franze8b98922014-11-12 15:57:54 +000070import java.util.HashMap;
Marie Janssen59804562016-12-28 14:13:21 -080071import java.util.LinkedList;
Benjamin Franze8b98922014-11-12 15:57:54 +000072import java.util.Map;
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";
Marie Janssene54b4222017-03-16 18:10:59 -070089 private static final String REASON_RESTARTED = "automatic restart";
90 private static final String REASON_START_CRASH = "turn-on crash";
Ajay Panicker467bc042017-02-22 12:23:15 -080091 private static final String REASON_SYSTEM_BOOT = "system boot";
Marie Janssene54b4222017-03-16 18:10:59 -070092 private static final String REASON_UNEXPECTED = "unexpected crash";
93 private static final String REASON_USER_SWITCH = "user switch";
94
fredc0f420372012-04-12 00:02:00 -070095 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +053096 //Maximum msec to wait for service restart
97 private static final int SERVICE_RESTART_TIME_MS = 200;
Zhihai Xudd9d17d2013-01-08 17:05:58 -080098 //Maximum msec to wait for restart due to error
99 private static final int ERROR_RESTART_TIME_MS = 3000;
Zhihai Xu40874a02012-10-08 17:57:03 -0700100 //Maximum msec to delay MESSAGE_USER_SWITCHED
101 private static final int USER_SWITCHED_TIME_MS = 200;
Benjamin Franze8b98922014-11-12 15:57:54 +0000102 // Delay for the addProxy function in msec
103 private static final int ADD_PROXY_DELAY_MS = 100;
fredc0f420372012-04-12 00:02:00 -0700104
105 private static final int MESSAGE_ENABLE = 1;
106 private static final int MESSAGE_DISABLE = 2;
fredc649fe492012-04-19 01:07:18 -0700107 private static final int MESSAGE_REGISTER_ADAPTER = 20;
108 private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
109 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
110 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
111 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
112 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +0530113 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700114 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
115 private static final int MESSAGE_TIMEOUT_BIND = 100;
116 private static final int MESSAGE_TIMEOUT_UNBIND = 101;
Ajay Panicker4bb48302016-03-31 14:14:27 -0700117 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
Zhihai Xu40874a02012-10-08 17:57:03 -0700118 private static final int MESSAGE_USER_SWITCHED = 300;
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700119 private static final int MESSAGE_USER_UNLOCKED = 301;
Benjamin Franze8b98922014-11-12 15:57:54 +0000120 private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
121 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
Marie Janssencb21ad72016-12-13 10:51:02 -0800122
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -0700123 private static final int MAX_SAVE_RETRIES = 3;
124 private static final int MAX_ERROR_RESTART_RETRIES = 6;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800125
Zhihai Xu401202b2012-12-03 11:36:21 -0800126 // Bluetooth persisted setting is off
127 private static final int BLUETOOTH_OFF=0;
128 // Bluetooth persisted setting is on
129 // and Airplane mode won't affect Bluetooth state at start up
130 private static final int BLUETOOTH_ON_BLUETOOTH=1;
131 // Bluetooth persisted setting is on
132 // but Airplane mode will affect Bluetooth state at start up
133 // and Airplane mode will have higher priority.
134 private static final int BLUETOOTH_ON_AIRPLANE=2;
fredc0f420372012-04-12 00:02:00 -0700135
Matthew Xieddf7e472013-03-01 18:41:02 -0800136 private static final int SERVICE_IBLUETOOTH = 1;
137 private static final int SERVICE_IBLUETOOTHGATT = 2;
138
fredc0f420372012-04-12 00:02:00 -0700139 private final Context mContext;
Matthew Xiecdce0b92012-07-12 19:06:15 -0700140
141 // Locks are not provided for mName and mAddress.
142 // They are accessed in handler or broadcast receiver, same thread context.
fredc0f420372012-04-12 00:02:00 -0700143 private String mAddress;
144 private String mName;
Matthew Xie6fde3092012-07-11 17:10:07 -0700145 private final ContentResolver mContentResolver;
146 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
147 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800148 private IBinder mBluetoothBinder;
fredc649fe492012-04-19 01:07:18 -0700149 private IBluetooth mBluetooth;
Matthew Xieddf7e472013-03-01 18:41:02 -0800150 private IBluetoothGatt mBluetoothGatt;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700151 private final ReentrantReadWriteLock mBluetoothLock =
152 new ReentrantReadWriteLock();
fredc649fe492012-04-19 01:07:18 -0700153 private boolean mBinding;
154 private boolean mUnbinding;
Marie Janssen59804562016-12-28 14:13:21 -0800155
Zhihai Xu401202b2012-12-03 11:36:21 -0800156 // used inside handler thread
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700157 private boolean mQuietEnable = false;
Marie Janssen59804562016-12-28 14:13:21 -0800158 private boolean mEnable;
159
Marie Janssene54b4222017-03-16 18:10:59 -0700160 private CharSequence timeToLog(long timestamp) {
161 return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
162 }
163
Marie Janssen59804562016-12-28 14:13:21 -0800164 /**
165 * Used for tracking apps that enabled / disabled Bluetooth.
166 */
167 private class ActiveLog {
168 private String mPackageName;
169 private boolean mEnable;
170 private long mTimestamp;
171
172 public ActiveLog(String packageName, boolean enable, long timestamp) {
173 mPackageName = packageName;
174 mEnable = enable;
175 mTimestamp = timestamp;
176 }
177
178 public long getTime() {
179 return mTimestamp;
180 }
181
182 public String toString() {
Marie Janssene54b4222017-03-16 18:10:59 -0700183 return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ") + " by "
184 + mPackageName;
Marie Janssen59804562016-12-28 14:13:21 -0800185 }
186
187 }
188
189 private LinkedList<ActiveLog> mActiveLogs;
Marie Janssene54b4222017-03-16 18:10:59 -0700190 private LinkedList<Long> mCrashTimestamps;
191 private int mCrashes;
Marie Janssen59804562016-12-28 14:13:21 -0800192
193 // configuration from external IBinder call which is used to
Zhihai Xu401202b2012-12-03 11:36:21 -0800194 // synchronize with broadcast receiver.
195 private boolean mQuietEnableExternal;
Zhihai Xu401202b2012-12-03 11:36:21 -0800196 private boolean mEnableExternal;
Marie Janssen59804562016-12-28 14:13:21 -0800197
198 // Map of apps registered to keep BLE scanning on.
199 private Map<IBinder, ClientDeathRecipient> mBleApps = new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
200
Zhihai Xu40874a02012-10-08 17:57:03 -0700201 private int mState;
Zhihai Xu40874a02012-10-08 17:57:03 -0700202 private final BluetoothHandler mHandler;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800203 private int mErrorRecoveryRetryCounter;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200204 private final int mSystemUiUid;
fredc0f420372012-04-12 00:02:00 -0700205
Benjamin Franze8b98922014-11-12 15:57:54 +0000206 // Save a ProfileServiceConnections object for each of the bound
207 // bluetooth profile services
208 private final Map <Integer, ProfileServiceConnections> mProfileServices =
209 new HashMap <Integer, ProfileServiceConnections>();
210
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700211 private final boolean mPermissionReviewRequired;
212
Marie Janssen59804562016-12-28 14:13:21 -0800213 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
fredcbf072a72012-05-09 16:52:50 -0700214 @Override
215 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
216 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
217 mHandler.sendMessage(msg);
218 }
219 };
220
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100221 private final UserRestrictionsListener mUserRestrictionsListener =
222 new UserRestrictionsListener() {
223 @Override
224 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
225 Bundle prevRestrictions) {
Lenka Trochtovac6f0e232017-01-17 10:35:49 +0100226 if (!newRestrictions.containsKey(UserManager.DISALLOW_BLUETOOTH)
227 && !prevRestrictions.containsKey(UserManager.DISALLOW_BLUETOOTH)) {
228 // The relevant restriction has not changed - do nothing.
229 return;
230 }
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100231 final boolean bluetoothDisallowed =
232 newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
233 if ((mEnable || mEnableExternal) && bluetoothDisallowed) {
234 try {
235 disable(null, true);
236 } catch (RemoteException e) {
237 Slog.w(TAG, "Exception when disabling Bluetooth from UserRestrictionsListener",
238 e);
239 }
240 }
Lenka Trochtovac6f0e232017-01-17 10:35:49 +0100241 updateOppLauncherComponentState(bluetoothDisallowed);
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100242 }
243 };
244
Ajay Panicker467bc042017-02-22 12:23:15 -0800245 private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
246 @Override
247 public void onChange(boolean unused) {
248 synchronized(this) {
249 if (isBluetoothPersistedStateOn()) {
250 if (isAirplaneModeOn()) {
251 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
252 } else {
253 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
254 }
255 }
256
257 int st = BluetoothAdapter.STATE_OFF;
258 try {
259 mBluetoothLock.readLock().lock();
260 if (mBluetooth != null) {
261 st = mBluetooth.getState();
262 }
263 } catch (RemoteException e) {
264 Slog.e(TAG, "Unable to call getState", e);
265 return;
266 } finally {
267 mBluetoothLock.readLock().unlock();
268 }
269
270 Slog.d(TAG, "Airplane Mode change - current state: " +
271 BluetoothAdapter.nameForState(st));
272
273 if (isAirplaneModeOn()) {
274 // Clear registered LE apps to force shut-off
275 clearBleApps();
276
277 // If state is BLE_ON make sure we trigger disableBLE
278 if (st == BluetoothAdapter.STATE_BLE_ON) {
279 try {
280 mBluetoothLock.readLock().lock();
281 if (mBluetooth != null) {
282 mBluetooth.onBrEdrDown();
283 mEnable = false;
284 mEnableExternal = false;
285 }
286 } catch (RemoteException e) {
287 Slog.e(TAG,"Unable to call onBrEdrDown", e);
288 } finally {
289 mBluetoothLock.readLock().unlock();
290 }
291 } else if (st == BluetoothAdapter.STATE_ON){
292 sendDisableMsg(REASON_AIRPLANE_MODE);
293 }
294 } else if (mEnableExternal) {
295 sendEnableMsg(mQuietEnableExternal, REASON_AIRPLANE_MODE);
296 }
297 }
298 }
299 };
300
fredcbf072a72012-05-09 16:52:50 -0700301 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
fredc0f420372012-04-12 00:02:00 -0700302 @Override
303 public void onReceive(Context context, Intent intent) {
304 String action = intent.getAction();
fredcbf072a72012-05-09 16:52:50 -0700305 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
fredc0f420372012-04-12 00:02:00 -0700306 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700307 if (DBG) Slog.d(TAG, "Bluetooth Adapter name changed to " + newName);
fredc0f420372012-04-12 00:02:00 -0700308 if (newName != null) {
309 storeNameAndAddress(newName, null);
310 }
Stanley Tngdd749b02017-04-17 22:35:45 -0700311 } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
312 String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
313 if (newAddress != null) {
314 if (DBG) Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
315 storeNameAndAddress(null, newAddress);
316 } else {
317 if (DBG) Slog.e(TAG, "No Bluetooth Adapter address parameter found");
318 }
fredc0f420372012-04-12 00:02:00 -0700319 }
320 }
321 };
322
323 BluetoothManagerService(Context context) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700324 mHandler = new BluetoothHandler(IoThread.get().getLooper());
Zhihai Xu40874a02012-10-08 17:57:03 -0700325
fredc0f420372012-04-12 00:02:00 -0700326 mContext = context;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700327
Svet Ganov77df6f32016-08-17 11:46:34 -0700328 mPermissionReviewRequired = context.getResources().getBoolean(
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700329 com.android.internal.R.bool.config_permissionReviewRequired);
330
Marie Janssen59804562016-12-28 14:13:21 -0800331 mActiveLogs = new LinkedList<ActiveLog>();
Marie Janssene54b4222017-03-16 18:10:59 -0700332 mCrashTimestamps = new LinkedList<Long>();
333 mCrashes = 0;
fredc0f420372012-04-12 00:02:00 -0700334 mBluetooth = null;
Marie Janssen9db28eb2016-01-12 16:05:15 -0800335 mBluetoothBinder = null;
Nitin Arorad055adb2015-03-02 15:03:51 -0800336 mBluetoothGatt = null;
fredc0f420372012-04-12 00:02:00 -0700337 mBinding = false;
338 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700339 mEnable = false;
340 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800341 mQuietEnableExternal = false;
342 mEnableExternal = false;
fredc0f420372012-04-12 00:02:00 -0700343 mAddress = null;
344 mName = null;
Zhihai Xudd9d17d2013-01-08 17:05:58 -0800345 mErrorRecoveryRetryCounter = 0;
fredc0f420372012-04-12 00:02:00 -0700346 mContentResolver = context.getContentResolver();
Wei Wange4a744b2015-06-11 17:50:29 -0700347 // Observe BLE scan only mode settings change.
348 registerForBleScanModeChange();
fredcd6883532012-04-25 17:46:13 -0700349 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
350 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
Miao Chou658bf2f2015-06-26 17:14:35 -0700351 IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
Dianne Hackbornd83a0962014-05-02 16:28:33 -0700352 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
Matthew Xie6fde3092012-07-11 17:10:07 -0700353 mContext.registerReceiver(mReceiver, filter);
Stanley Tngdd749b02017-04-17 22:35:45 -0700354 filter = new IntentFilter(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
355 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
356 mContext.registerReceiver(mReceiver, filter);
fredc0f420372012-04-12 00:02:00 -0700357 loadStoredNameAndAddress();
Zhihai Xu401202b2012-12-03 11:36:21 -0800358 if (isBluetoothPersistedStateOn()) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700359 if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
Zhihai Xu401202b2012-12-03 11:36:21 -0800360 mEnableExternal = true;
fredc0f420372012-04-12 00:02:00 -0700361 }
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200362
Ajay Panicker467bc042017-02-22 12:23:15 -0800363 String airplaneModeRadios = Settings.Global.getString(mContentResolver,
364 Settings.Global.AIRPLANE_MODE_RADIOS);
365 if (airplaneModeRadios == null ||
366 airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
367 mContentResolver.registerContentObserver(
368 Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
369 true, mAirplaneModeObserver);
370 }
371
Marie Janssen59804562016-12-28 14:13:21 -0800372 int systemUiUid = -1;
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200373 try {
Marie Janssen59804562016-12-28 14:13:21 -0800374 systemUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui",
Jeff Sharkeyc5967e92016-01-07 18:50:29 -0700375 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200376 } catch (PackageManager.NameNotFoundException e) {
Joe LaPennaacddf2b2015-09-04 12:52:42 -0700377 // Some platforms, such as wearables do not have a system ui.
Jeff Sharkey67609c72016-03-05 14:29:13 -0700378 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e);
Adrian Roosbd9a9a52014-08-18 15:31:57 +0200379 }
Marie Janssen59804562016-12-28 14:13:21 -0800380 mSystemUiUid = systemUiUid;
fredc0f420372012-04-12 00:02:00 -0700381 }
382
fredc649fe492012-04-19 01:07:18 -0700383 /**
384 * Returns true if airplane mode is currently on
385 */
386 private final boolean isAirplaneModeOn() {
Christopher Tatec09cdce2012-09-10 16:50:14 -0700387 return Settings.Global.getInt(mContext.getContentResolver(),
388 Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
fredc649fe492012-04-19 01:07:18 -0700389 }
390
391 /**
392 * Returns true if the Bluetooth saved state is "on"
393 */
394 private final boolean isBluetoothPersistedStateOn() {
Marie Janssen9fa24912016-10-18 10:04:24 -0700395 int state = Settings.Global.getInt(mContentResolver,
396 Settings.Global.BLUETOOTH_ON, -1);
397 if (DBG) Slog.d(TAG, "Bluetooth persisted state: " + state);
398 return state != BLUETOOTH_OFF;
Zhihai Xu401202b2012-12-03 11:36:21 -0800399 }
400
401 /**
402 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
403 */
404 private final boolean isBluetoothPersistedStateOnBluetooth() {
405 return Settings.Global.getInt(mContentResolver,
Andre Eisenbach8c184312016-09-06 18:03:10 -0700406 Settings.Global.BLUETOOTH_ON, BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH;
fredc649fe492012-04-19 01:07:18 -0700407 }
408
409 /**
410 * Save the Bluetooth on/off state
fredc649fe492012-04-19 01:07:18 -0700411 */
Zhihai Xu401202b2012-12-03 11:36:21 -0800412 private void persistBluetoothSetting(int value) {
Marie Janssen9fa24912016-10-18 10:04:24 -0700413 if (DBG) Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
Marie Janssenfa630682016-12-15 13:51:30 -0800414 // waive WRITE_SECURE_SETTINGS permission check
415 long callingIdentity = Binder.clearCallingIdentity();
Jeff Brownbf6f6f92012-09-25 15:03:20 -0700416 Settings.Global.putInt(mContext.getContentResolver(),
417 Settings.Global.BLUETOOTH_ON,
Zhihai Xu401202b2012-12-03 11:36:21 -0800418 value);
Marie Janssenfa630682016-12-15 13:51:30 -0800419 Binder.restoreCallingIdentity(callingIdentity);
fredc649fe492012-04-19 01:07:18 -0700420 }
421
422 /**
423 * Returns true if the Bluetooth Adapter's name and address is
424 * locally cached
425 * @return
426 */
fredc0f420372012-04-12 00:02:00 -0700427 private boolean isNameAndAddressSet() {
428 return mName !=null && mAddress!= null && mName.length()>0 && mAddress.length()>0;
429 }
430
fredc649fe492012-04-19 01:07:18 -0700431 /**
432 * Retrieve the Bluetooth Adapter's name and address and save it in
433 * in the local cache
434 */
fredc0f420372012-04-12 00:02:00 -0700435 private void loadStoredNameAndAddress() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700436 if (DBG) Slog.d(TAG, "Loading stored name and address");
Zhihai Xud31c3222012-10-31 16:08:57 -0700437 if (mContext.getResources().getBoolean
438 (com.android.internal.R.bool.config_bluetooth_address_validation) &&
439 Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0) == 0) {
440 // if the valid flag is not set, don't load the address and name
Jeff Sharkey67609c72016-03-05 14:29:13 -0700441 if (DBG) Slog.d(TAG, "invalid bluetooth name and address stored");
Zhihai Xud31c3222012-10-31 16:08:57 -0700442 return;
443 }
fredc0f420372012-04-12 00:02:00 -0700444 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
445 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
Jeff Sharkey67609c72016-03-05 14:29:13 -0700446 if (DBG) Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
fredc0f420372012-04-12 00:02:00 -0700447 }
448
fredc649fe492012-04-19 01:07:18 -0700449 /**
450 * Save the Bluetooth name and address in the persistent store.
451 * Only non-null values will be saved.
452 * @param name
453 * @param address
454 */
fredc0f420372012-04-12 00:02:00 -0700455 private void storeNameAndAddress(String name, String address) {
456 if (name != null) {
457 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
fredc0f420372012-04-12 00:02:00 -0700458 mName = name;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700459 if (DBG) Slog.d(TAG,"Stored Bluetooth name: " +
fredc649fe492012-04-19 01:07:18 -0700460 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_NAME));
fredc0f420372012-04-12 00:02:00 -0700461 }
462
463 if (address != null) {
464 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
fredc0f420372012-04-12 00:02:00 -0700465 mAddress=address;
Jeff Sharkey67609c72016-03-05 14:29:13 -0700466 if (DBG) Slog.d(TAG,"Stored Bluetoothaddress: " +
fredc649fe492012-04-19 01:07:18 -0700467 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS));
fredc0f420372012-04-12 00:02:00 -0700468 }
Zhihai Xud31c3222012-10-31 16:08:57 -0700469
470 if ((name != null) && (address != null)) {
471 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
472 }
fredc0f420372012-04-12 00:02:00 -0700473 }
474
475 public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700476 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700477 Slog.w(TAG, "Callback is null in registerAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700478 return null;
479 }
fredc0f420372012-04-12 00:02:00 -0700480 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
481 msg.obj = callback;
482 mHandler.sendMessage(msg);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700483
484 return mBluetooth;
fredc0f420372012-04-12 00:02:00 -0700485 }
486
487 public void unregisterAdapter(IBluetoothManagerCallback callback) {
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700488 if (callback == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700489 Slog.w(TAG, "Callback is null in unregisterAdapter");
Natalie Silvanovich55db6462014-05-01 16:12:23 -0700490 return;
491 }
fredc0f420372012-04-12 00:02:00 -0700492 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
493 "Need BLUETOOTH permission");
494 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
495 msg.obj = callback;
496 mHandler.sendMessage(msg);
497 }
498
499 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
500 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
501 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800502 if (callback == null) {
503 Slog.w(TAG, "registerStateChangeCallback: Callback is null!");
504 return;
505 }
fredc0f420372012-04-12 00:02:00 -0700506 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
507 msg.obj = callback;
508 mHandler.sendMessage(msg);
509 }
510
511 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
512 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
513 "Need BLUETOOTH permission");
Marie Janssencb21ad72016-12-13 10:51:02 -0800514 if (callback == null) {
515 Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!");
516 return;
517 }
fredc0f420372012-04-12 00:02:00 -0700518 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
519 msg.obj = callback;
520 mHandler.sendMessage(msg);
521 }
522
523 public boolean isEnabled() {
Zhihai Xu6eb76522012-11-29 15:41:04 -0800524 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
525 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700526 Slog.w(TAG,"isEnabled(): not allowed for non-active and non system user");
Zhihai Xu40874a02012-10-08 17:57:03 -0700527 return false;
528 }
529
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700530 try {
531 mBluetoothLock.readLock().lock();
532 if (mBluetooth != null) return mBluetooth.isEnabled();
533 } catch (RemoteException e) {
534 Slog.e(TAG, "isEnabled()", e);
535 } finally {
536 mBluetoothLock.readLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700537 }
538 return false;
539 }
540
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700541 public int getState() {
542 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
543 (!checkIfCallerIsForegroundUser())) {
Marie Janssencb21ad72016-12-13 10:51:02 -0800544 Slog.w(TAG, "getState(): report OFF for non-active and non system user");
Christine Hallstrom995c90a2016-05-25 15:49:08 -0700545 return BluetoothAdapter.STATE_OFF;
546 }
547
548 try {
549 mBluetoothLock.readLock().lock();
550 if (mBluetooth != null) return mBluetooth.getState();
551 } catch (RemoteException e) {
552 Slog.e(TAG, "getState()", e);
553 } finally {
554 mBluetoothLock.readLock().unlock();
555 }
556 return BluetoothAdapter.STATE_OFF;
557 }
558
Nitin Arorad055adb2015-03-02 15:03:51 -0800559 class ClientDeathRecipient implements IBinder.DeathRecipient {
Marie Janssen59804562016-12-28 14:13:21 -0800560 private String mPackageName;
561
562 public ClientDeathRecipient(String packageName) {
563 mPackageName = packageName;
564 }
565
Nitin Arorad055adb2015-03-02 15:03:51 -0800566 public void binderDied() {
Marie Janssen59804562016-12-28 14:13:21 -0800567 if (DBG) Slog.d(TAG, "Binder is dead - unregister " + mPackageName);
Marie Janssen2977c3e2016-11-09 12:01:24 -0800568 if (isBleAppPresent()) {
569 // Nothing to do, another app is here.
570 return;
571 }
572 if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash");
573 try {
574 mBluetoothLock.readLock().lock();
575 if (mBluetooth != null &&
576 mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
577 mEnable = false;
578 mBluetooth.onBrEdrDown();
Nitin Arorad055adb2015-03-02 15:03:51 -0800579 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800580 } catch (RemoteException e) {
581 Slog.e(TAG,"Unable to call onBrEdrDown", e);
582 } finally {
583 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800584 }
585 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800586
Marie Janssen59804562016-12-28 14:13:21 -0800587 public String getPackageName() {
588 return mPackageName;
589 }
590 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800591
Wei Wang67d84162015-04-26 17:04:29 -0700592 @Override
593 public boolean isBleScanAlwaysAvailable() {
Marie Janssena80d7452016-10-25 10:47:51 -0700594 if (isAirplaneModeOn() && !mEnable) {
595 return false;
596 }
Wei Wang67d84162015-04-26 17:04:29 -0700597 try {
598 return (Settings.Global.getInt(mContentResolver,
599 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE)) != 0;
600 } catch (SettingNotFoundException e) {
601 }
602 return false;
603 }
604
Wei Wange4a744b2015-06-11 17:50:29 -0700605 // Monitor change of BLE scan only mode settings.
606 private void registerForBleScanModeChange() {
607 ContentObserver contentObserver = new ContentObserver(null) {
608 @Override
609 public void onChange(boolean selfChange) {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800610 if (isBleScanAlwaysAvailable()) {
611 // Nothing to do
612 return;
613 }
614 // BLE scan is not available.
615 disableBleScanMode();
616 clearBleApps();
617 try {
618 mBluetoothLock.readLock().lock();
619 if (mBluetooth != null) mBluetooth.onBrEdrDown();
620 } catch (RemoteException e) {
621 Slog.e(TAG, "error when disabling bluetooth", e);
622 } finally {
623 mBluetoothLock.readLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700624 }
625 }
626 };
627
628 mContentResolver.registerContentObserver(
629 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE),
630 false, contentObserver);
631 }
632
633 // Disable ble scan only mode.
634 private void disableBleScanMode() {
635 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700636 mBluetoothLock.writeLock().lock();
Wei Wange4a744b2015-06-11 17:50:29 -0700637 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700638 if (DBG) Slog.d(TAG, "Reseting the mEnable flag for clean disable");
Wei Wange4a744b2015-06-11 17:50:29 -0700639 mEnable = false;
640 }
641 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700642 Slog.e(TAG, "getState()", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700643 } finally {
644 mBluetoothLock.writeLock().unlock();
Wei Wange4a744b2015-06-11 17:50:29 -0700645 }
646 }
647
Marie Janssen59804562016-12-28 14:13:21 -0800648 public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
649 ClientDeathRecipient r = mBleApps.get(token);
650 if (r == null && enable) {
651 ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
652 try {
653 token.linkToDeath(deathRec, 0);
654 } catch (RemoteException ex) {
655 throw new IllegalArgumentException("BLE app (" + packageName + ") already dead!");
Nitin Arorad055adb2015-03-02 15:03:51 -0800656 }
Marie Janssen59804562016-12-28 14:13:21 -0800657 mBleApps.put(token, deathRec);
658 if (DBG) Slog.d(TAG, "Registered for death of " + packageName);
659 } else if (!enable && r != null) {
660 // Unregister death recipient as the app goes away.
661 token.unlinkToDeath(r, 0);
662 mBleApps.remove(token);
663 if (DBG) Slog.d(TAG, "Unregistered for death of " + packageName);
Nitin Arorad055adb2015-03-02 15:03:51 -0800664 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800665 int appCount = mBleApps.size();
666 if (DBG) Slog.d(TAG, appCount + " registered Ble Apps");
667 if (appCount == 0 && mEnable) {
Wei Wange4a744b2015-06-11 17:50:29 -0700668 disableBleScanMode();
Nitin Arorad055adb2015-03-02 15:03:51 -0800669 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800670 if (appCount == 0 && !mEnableExternal) {
671 sendBrEdrDownCallback();
672 }
Marie Janssen2977c3e2016-11-09 12:01:24 -0800673 return appCount;
Nitin Arorad055adb2015-03-02 15:03:51 -0800674 }
675
Wei Wange4a744b2015-06-11 17:50:29 -0700676 // Clear all apps using BLE scan only mode.
677 private void clearBleApps() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800678 mBleApps.clear();
Wei Wange4a744b2015-06-11 17:50:29 -0700679 }
680
Marie Janssen59804562016-12-28 14:13:21 -0800681 /** @hide */
Nitin Arorad055adb2015-03-02 15:03:51 -0800682 public boolean isBleAppPresent() {
Marie Janssen2977c3e2016-11-09 12:01:24 -0800683 if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleApps.size());
684 return mBleApps.size() > 0;
Nitin Arorad055adb2015-03-02 15:03:51 -0800685 }
686
687 /**
Marie Janssenfa630682016-12-15 13:51:30 -0800688 * Action taken when GattService is turned on
Nitin Arorad055adb2015-03-02 15:03:51 -0800689 */
690 private void onBluetoothGattServiceUp() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700691 if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700692 try {
693 mBluetoothLock.readLock().lock();
Marie Janssenfa630682016-12-15 13:51:30 -0800694 if (mBluetooth == null) {
695 if (DBG) Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!");
696 return;
697 }
698 int st = mBluetooth.getState();
699 if (st != BluetoothAdapter.STATE_BLE_ON) {
700 if (DBG) Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " +
701 BluetoothAdapter.nameForState(st));
702 return;
703 }
704 if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
705 // This triggers transition to STATE_ON
Nitin Arorad055adb2015-03-02 15:03:51 -0800706 mBluetooth.onLeServiceUp();
Nitin Arorad055adb2015-03-02 15:03:51 -0800707 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Nitin Arorad055adb2015-03-02 15:03:51 -0800708 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700709 } catch (RemoteException e) {
710 Slog.e(TAG,"Unable to call onServiceUp", e);
711 } finally {
712 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800713 }
714 }
715
716 /**
717 * Inform BluetoothAdapter instances that BREDR part is down
718 * and turn off all service and stack if no LE app needs it
719 */
720 private void sendBrEdrDownCallback() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700721 if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700722
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700723 if (mBluetooth == null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700724 Slog.w(TAG, "Bluetooth handle is null");
Nitin Arorabdfaa7f2015-04-29 12:35:03 -0700725 return;
726 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800727
Martin Brabhamc2b06222017-02-27 16:55:07 -0800728 if (isBleAppPresent()) {
729 // Need to stay at BLE ON. Disconnect all Gatt connections
730 try {
731 mBluetoothGatt.unregAll();
732 } catch (RemoteException e) {
733 Slog.e(TAG, "Unable to disconnect all apps.", e);
734 }
735 } else {
Nitin Arorad055adb2015-03-02 15:03:51 -0800736 try {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700737 mBluetoothLock.readLock().lock();
738 if (mBluetooth != null) mBluetooth.onBrEdrDown();
739 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700740 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700741 } finally {
742 mBluetoothLock.readLock().unlock();
Nitin Arorad055adb2015-03-02 15:03:51 -0800743 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800744 }
Martin Brabhamc2b06222017-02-27 16:55:07 -0800745
Nitin Arorad055adb2015-03-02 15:03:51 -0800746 }
747
Marie Janssen59804562016-12-28 14:13:21 -0800748 public boolean enableNoAutoConnect(String packageName)
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700749 {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100750 if (isBluetoothDisallowed()) {
751 if (DBG) {
752 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
753 }
754 return false;
755 }
756
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700757 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
758 "Need BLUETOOTH ADMIN permission");
Zhihai Xu40874a02012-10-08 17:57:03 -0700759
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700760 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700761 Slog.d(TAG,"enableNoAutoConnect(): mBluetooth =" + mBluetooth +
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700762 " mBinding = " + mBinding);
763 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800764 int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
765
766 if (callingAppId != Process.NFC_UID) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700767 throw new SecurityException("no permission to enable Bluetooth quietly");
768 }
Martijn Coenen8385c5a2012-11-29 10:14:16 -0800769
Zhihai Xu401202b2012-12-03 11:36:21 -0800770 synchronized(mReceiver) {
771 mQuietEnableExternal = true;
772 mEnableExternal = true;
Marie Janssen59804562016-12-28 14:13:21 -0800773 sendEnableMsg(true, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800774 }
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700775 return true;
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -0700776 }
Ajay Panicker4bb48302016-03-31 14:14:27 -0700777
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700778 public boolean enable(String packageName) throws RemoteException {
779 final int callingUid = Binder.getCallingUid();
780 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
781
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100782 if (isBluetoothDisallowed()) {
783 if (DBG) {
784 Slog.d(TAG,"enable(): not enabling - bluetooth disallowed");
785 }
786 return false;
787 }
788
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700789 if (!callerSystem) {
790 if (!checkIfCallerIsForegroundUser()) {
791 Slog.w(TAG, "enable(): not allowed for non-active and non system user");
792 return false;
793 }
794
795 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
796 "Need BLUETOOTH ADMIN permission");
797
798 if (!isEnabled() && mPermissionReviewRequired
799 && startConsentUiIfNeeded(packageName, callingUid,
800 BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
801 return false;
802 }
fredcf2458862012-04-16 15:18:27 -0700803 }
804
Zhihai Xu401202b2012-12-03 11:36:21 -0800805 if (DBG) {
Marie Janssen59804562016-12-28 14:13:21 -0800806 Slog.d(TAG,"enable(" + packageName + "): mBluetooth =" + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800807 " mBinding = " + mBinding + " mState = " +
808 BluetoothAdapter.nameForState(mState));
Sanket Agarwal090bf552016-04-21 14:10:55 -0700809 }
Zhihai Xu401202b2012-12-03 11:36:21 -0800810
811 synchronized(mReceiver) {
812 mQuietEnableExternal = false;
813 mEnableExternal = true;
814 // waive WRITE_SECURE_SETTINGS permission check
Marie Janssen59804562016-12-28 14:13:21 -0800815 sendEnableMsg(false, packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800816 }
Jeff Sharkey67609c72016-03-05 14:29:13 -0700817 if (DBG) Slog.d(TAG, "enable returning");
Zhihai Xu401202b2012-12-03 11:36:21 -0800818 return true;
fredc0f420372012-04-12 00:02:00 -0700819 }
820
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700821 public boolean disable(String packageName, boolean persist) throws RemoteException {
822 final int callingUid = Binder.getCallingUid();
823 final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
Zhihai Xu40874a02012-10-08 17:57:03 -0700824
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700825 if (!callerSystem) {
826 if (!checkIfCallerIsForegroundUser()) {
827 Slog.w(TAG, "disable(): not allowed for non-active and non system user");
828 return false;
829 }
830
831 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
832 "Need BLUETOOTH ADMIN permission");
833
834 if (isEnabled() && mPermissionReviewRequired
835 && startConsentUiIfNeeded(packageName, callingUid,
836 BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
837 return false;
838 }
Zhihai Xu40874a02012-10-08 17:57:03 -0700839 }
840
fredcf2458862012-04-16 15:18:27 -0700841 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700842 Slog.d(TAG,"disable(): mBluetooth = " + mBluetooth +
Matthew Xiecdce0b92012-07-12 19:06:15 -0700843 " mBinding = " + mBinding);
844 }
fredcf2458862012-04-16 15:18:27 -0700845
Zhihai Xu401202b2012-12-03 11:36:21 -0800846 synchronized(mReceiver) {
847 if (persist) {
Zhihai Xu401202b2012-12-03 11:36:21 -0800848 persistBluetoothSetting(BLUETOOTH_OFF);
Zhihai Xu401202b2012-12-03 11:36:21 -0800849 }
850 mEnableExternal = false;
Marie Janssen59804562016-12-28 14:13:21 -0800851 sendDisableMsg(packageName);
Zhihai Xu401202b2012-12-03 11:36:21 -0800852 }
fredc0f420372012-04-12 00:02:00 -0700853 return true;
854 }
855
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700856 private boolean startConsentUiIfNeeded(String packageName,
857 int callingUid, String intentAction) throws RemoteException {
858 try {
859 // Validate the package only if we are going to use it
860 ApplicationInfo applicationInfo = mContext.getPackageManager()
861 .getApplicationInfoAsUser(packageName,
862 PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
863 UserHandle.getUserId(callingUid));
864 if (applicationInfo.uid != callingUid) {
865 throw new SecurityException("Package " + callingUid
866 + " not in uid " + callingUid);
867 }
868
Ivan Podogovd2d32b12016-12-05 16:46:52 +0000869 Intent intent = new Intent(intentAction);
Ivan Podogov1ab87252017-01-03 12:02:18 +0000870 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
871 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
872 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
873 try {
874 mContext.startActivity(intent);
875 } catch (ActivityNotFoundException e) {
876 // Shouldn't happen
877 Slog.e(TAG, "Intent to handle action " + intentAction + " missing");
878 return false;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700879 }
Ivan Podogov1ab87252017-01-03 12:02:18 +0000880 return true;
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700881 } catch (PackageManager.NameNotFoundException e) {
882 throw new RemoteException(e.getMessage());
883 }
Svetoslav Ganovac69be52016-06-29 17:31:44 -0700884 }
885
fredc649fe492012-04-19 01:07:18 -0700886 public void unbindAndFinish() {
fredcf2458862012-04-16 15:18:27 -0700887 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700888 Slog.d(TAG,"unbindAndFinish(): " + mBluetooth +
Marie Janssencb21ad72016-12-13 10:51:02 -0800889 " mBinding = " + mBinding + " mUnbinding = " + mUnbinding);
fredcf2458862012-04-16 15:18:27 -0700890 }
891
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700892 try {
893 mBluetoothLock.writeLock().lock();
fredc0f420372012-04-12 00:02:00 -0700894 if (mUnbinding) return;
895 mUnbinding = true;
Pavlin Radoslavove47ec142016-06-01 22:25:18 -0700896 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
Pavlin Radoslavov74f60c02016-09-21 17:28:11 -0700897 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE);
Zhihai Xu40874a02012-10-08 17:57:03 -0700898 if (mBluetooth != null) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -0800899 //Unregister callback object
900 try {
901 mBluetooth.unregisterCallback(mBluetoothCallback);
902 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700903 Slog.e(TAG, "Unable to unregister BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -0700904 }
Marie Janssen9db28eb2016-01-12 16:05:15 -0800905 mBluetoothBinder = null;
fredcd6883532012-04-25 17:46:13 -0700906 mBluetooth = null;
fredc0f420372012-04-12 00:02:00 -0700907 mContext.unbindService(mConnection);
fredcd6883532012-04-25 17:46:13 -0700908 mUnbinding = false;
Zhihai Xu40874a02012-10-08 17:57:03 -0700909 mBinding = false;
fredcf2458862012-04-16 15:18:27 -0700910 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -0800911 mUnbinding = false;
fredc0f420372012-04-12 00:02:00 -0700912 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800913 mBluetoothGatt = null;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -0700914 } finally {
915 mBluetoothLock.writeLock().unlock();
fredc0f420372012-04-12 00:02:00 -0700916 }
917 }
918
Matthew Xieddf7e472013-03-01 18:41:02 -0800919 public IBluetoothGatt getBluetoothGatt() {
920 // sync protection
921 return mBluetoothGatt;
922 }
923
Benjamin Franze8b98922014-11-12 15:57:54 +0000924 @Override
925 public boolean bindBluetoothProfileService(int bluetoothProfile,
926 IBluetoothProfileServiceConnection proxy) {
927 if (!mEnable) {
928 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700929 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile +
Benjamin Franze8b98922014-11-12 15:57:54 +0000930 ", while Bluetooth was disabled");
931 }
932 return false;
933 }
934 synchronized (mProfileServices) {
935 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
936 if (psc == null) {
937 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700938 Slog.d(TAG, "Creating new ProfileServiceConnections object for"
Benjamin Franze8b98922014-11-12 15:57:54 +0000939 + " profile: " + bluetoothProfile);
940 }
Benjamin Franz5b614592014-12-09 18:58:45 +0000941
942 if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
943
944 Intent intent = new Intent(IBluetoothHeadset.class.getName());
Benjamin Franze8b98922014-11-12 15:57:54 +0000945 psc = new ProfileServiceConnections(intent);
Benjamin Franz5b614592014-12-09 18:58:45 +0000946 if (!psc.bindService()) return false;
947
Benjamin Franze8b98922014-11-12 15:57:54 +0000948 mProfileServices.put(new Integer(bluetoothProfile), psc);
Benjamin Franze8b98922014-11-12 15:57:54 +0000949 }
950 }
951
952 // Introducing a delay to give the client app time to prepare
953 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED);
954 addProxyMsg.arg1 = bluetoothProfile;
955 addProxyMsg.obj = proxy;
956 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS);
957 return true;
958 }
959
960 @Override
961 public void unbindBluetoothProfileService(int bluetoothProfile,
962 IBluetoothProfileServiceConnection proxy) {
963 synchronized (mProfileServices) {
964 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile));
965 if (psc == null) {
966 return;
967 }
968 psc.removeProxy(proxy);
969 }
970 }
971
972 private void unbindAllBluetoothProfileServices() {
973 synchronized (mProfileServices) {
974 for (Integer i : mProfileServices.keySet()) {
975 ProfileServiceConnections psc = mProfileServices.get(i);
Benjamin Franz5b614592014-12-09 18:58:45 +0000976 try {
977 mContext.unbindService(psc);
978 } catch (IllegalArgumentException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700979 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
Benjamin Franz5b614592014-12-09 18:58:45 +0000980 }
Benjamin Franze8b98922014-11-12 15:57:54 +0000981 psc.removeAllProxies();
982 }
983 mProfileServices.clear();
984 }
985 }
986
987 /**
Miao Chou658bf2f2015-06-26 17:14:35 -0700988 * Send enable message and set adapter name and address. Called when the boot phase becomes
989 * PHASE_SYSTEM_SERVICES_READY.
990 */
991 public void handleOnBootPhase() {
Jeff Sharkey67609c72016-03-05 14:29:13 -0700992 if (DBG) Slog.d(TAG, "Bluetooth boot completed");
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +0100993 UserManagerInternal userManagerInternal =
994 LocalServices.getService(UserManagerInternal.class);
995 userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
Lenka Trochtovac6f0e232017-01-17 10:35:49 +0100996 final boolean isBluetoothDisallowed = isBluetoothDisallowed();
997 PackageManagerService packageManagerService =
998 (PackageManagerService) ServiceManager.getService("package");
999 if (packageManagerService != null && !packageManagerService.isOnlyCoreApps()) {
1000 updateOppLauncherComponentState(isBluetoothDisallowed);
1001 }
1002 if (isBluetoothDisallowed) {
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01001003 return;
1004 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001005 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001006 if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
Ajay Panicker467bc042017-02-22 12:23:15 -08001007 sendEnableMsg(mQuietEnableExternal, REASON_SYSTEM_BOOT);
Ajay Panickerbf796d82016-03-11 13:47:20 -08001008 } else if (!isNameAndAddressSet()) {
1009 if (DBG) Slog.d(TAG, "Getting adapter name and address");
Ajay Panicker4bb48302016-03-31 14:14:27 -07001010 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1011 mHandler.sendMessage(getMsg);
Miao Chou658bf2f2015-06-26 17:14:35 -07001012 }
Miao Chou658bf2f2015-06-26 17:14:35 -07001013 }
1014
1015 /**
1016 * Called when switching to a different foreground user.
1017 */
1018 public void handleOnSwitchUser(int userHandle) {
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001019 if (DBG) Slog.d(TAG, "User " + userHandle + " switched");
1020 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget();
1021 }
1022
1023 /**
1024 * Called when user is unlocked.
1025 */
1026 public void handleOnUnlockUser(int userHandle) {
1027 if (DBG) Slog.d(TAG, "User " + userHandle + " unlocked");
1028 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget();
Miao Chou658bf2f2015-06-26 17:14:35 -07001029 }
1030
1031 /**
Benjamin Franze8b98922014-11-12 15:57:54 +00001032 * This class manages the clients connected to a given ProfileService
1033 * and maintains the connection with that service.
1034 */
1035 final private class ProfileServiceConnections implements ServiceConnection,
1036 IBinder.DeathRecipient {
1037 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies =
1038 new RemoteCallbackList <IBluetoothProfileServiceConnection>();
1039 IBinder mService;
1040 ComponentName mClassName;
1041 Intent mIntent;
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001042 boolean mInvokingProxyCallbacks = false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001043
1044 ProfileServiceConnections(Intent intent) {
1045 mService = null;
1046 mClassName = null;
1047 mIntent = intent;
1048 }
1049
Benjamin Franz5b614592014-12-09 18:58:45 +00001050 private boolean bindService() {
1051 if (mIntent != null && mService == null &&
1052 doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Benjamin Franze8b98922014-11-12 15:57:54 +00001053 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1054 msg.obj = this;
1055 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
Benjamin Franz5b614592014-12-09 18:58:45 +00001056 return true;
Benjamin Franze8b98922014-11-12 15:57:54 +00001057 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001058 Slog.w(TAG, "Unable to bind with intent: " + mIntent);
Benjamin Franz5b614592014-12-09 18:58:45 +00001059 return false;
Benjamin Franze8b98922014-11-12 15:57:54 +00001060 }
1061
1062 private void addProxy(IBluetoothProfileServiceConnection proxy) {
1063 mProxies.register(proxy);
1064 if (mService != null) {
1065 try{
1066 proxy.onServiceConnected(mClassName, mService);
1067 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001068 Slog.e(TAG, "Unable to connect to proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001069 }
1070 } else {
1071 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) {
1072 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1073 msg.obj = this;
1074 mHandler.sendMessage(msg);
1075 }
1076 }
1077 }
1078
1079 private void removeProxy(IBluetoothProfileServiceConnection proxy) {
1080 if (proxy != null) {
1081 if (mProxies.unregister(proxy)) {
1082 try {
1083 proxy.onServiceDisconnected(mClassName);
1084 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001085 Slog.e(TAG, "Unable to disconnect proxy", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001086 }
1087 }
1088 } else {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001089 Slog.w(TAG, "Trying to remove a null proxy");
Benjamin Franze8b98922014-11-12 15:57:54 +00001090 }
1091 }
1092
1093 private void removeAllProxies() {
1094 onServiceDisconnected(mClassName);
1095 mProxies.kill();
1096 }
1097
1098 @Override
1099 public void onServiceConnected(ComponentName className, IBinder service) {
1100 // remove timeout message
1101 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this);
1102 mService = service;
1103 mClassName = className;
1104 try {
1105 mService.linkToDeath(this, 0);
1106 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001107 Slog.e(TAG, "Unable to linkToDeath", e);
Benjamin Franze8b98922014-11-12 15:57:54 +00001108 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001109
1110 if (mInvokingProxyCallbacks) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001111 Slog.e(TAG, "Proxy callbacks already in progress.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001112 return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001113 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001114 mInvokingProxyCallbacks = true;
1115
1116 final int n = mProxies.beginBroadcast();
1117 try {
1118 for (int i = 0; i < n; i++) {
1119 try {
1120 mProxies.getBroadcastItem(i).onServiceConnected(className, service);
1121 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001122 Slog.e(TAG, "Unable to connect to proxy", e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001123 }
1124 }
1125 } finally {
1126 mProxies.finishBroadcast();
1127 mInvokingProxyCallbacks = false;
1128 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001129 }
1130
1131 @Override
1132 public void onServiceDisconnected(ComponentName className) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001133 if (mService == null) return;
Benjamin Franze8b98922014-11-12 15:57:54 +00001134 mService.unlinkToDeath(this, 0);
1135 mService = null;
1136 mClassName = null;
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).onServiceDisconnected(className);
1149 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001150 Slog.e(TAG, "Unable to disconnect from 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 binderDied() {
1161 if (DBG) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001162 Slog.w(TAG, "Profile service for profile: " + mClassName
Benjamin Franze8b98922014-11-12 15:57:54 +00001163 + " died.");
1164 }
1165 onServiceDisconnected(mClassName);
1166 // Trigger rebind
1167 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
1168 msg.obj = this;
1169 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
1170 }
1171 }
1172
fredcbf072a72012-05-09 16:52:50 -07001173 private void sendBluetoothStateCallback(boolean isUp) {
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001174 try {
1175 int n = mStateChangeCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001176 if (DBG) Slog.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001177 for (int i=0; i <n;i++) {
1178 try {
1179 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
1180 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001181 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001182 }
fredcbf072a72012-05-09 16:52:50 -07001183 }
Andre Eisenbach3bf1ac52015-07-30 08:59:32 -07001184 } finally {
1185 mStateChangeCallbacks.finishBroadcast();
fredcbf072a72012-05-09 16:52:50 -07001186 }
fredcbf072a72012-05-09 16:52:50 -07001187 }
1188
1189 /**
Zhihai Xu40874a02012-10-08 17:57:03 -07001190 * Inform BluetoothAdapter instances that Adapter service is up
1191 */
1192 private void sendBluetoothServiceUpCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001193 try {
1194 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001195 Slog.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001196 for (int i=0; i <n;i++) {
1197 try {
1198 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
1199 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001200 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
Zhihai Xu40874a02012-10-08 17:57:03 -07001201 }
1202 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001203 } finally {
1204 mCallbacks.finishBroadcast();
Zhihai Xu40874a02012-10-08 17:57:03 -07001205 }
1206 }
1207 /**
fredcbf072a72012-05-09 16:52:50 -07001208 * Inform BluetoothAdapter instances that Adapter service is down
1209 */
1210 private void sendBluetoothServiceDownCallback() {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001211 try {
1212 int n = mCallbacks.beginBroadcast();
Jeff Sharkey67609c72016-03-05 14:29:13 -07001213 Slog.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001214 for (int i=0; i <n;i++) {
1215 try {
1216 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
1217 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001218 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
fredcd6883532012-04-25 17:46:13 -07001219 }
1220 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001221 } finally {
1222 mCallbacks.finishBroadcast();
fredcd6883532012-04-25 17:46:13 -07001223 }
1224 }
Svet Ganov408abf72015-05-12 19:13:36 -07001225
fredc0f420372012-04-12 00:02:00 -07001226 public String getAddress() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001227 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
Svet Ganov408abf72015-05-12 19:13:36 -07001228 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001229
Zhihai Xu6eb76522012-11-29 15:41:04 -08001230 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
Svet Ganov408abf72015-05-12 19:13:36 -07001231 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001232 Slog.w(TAG,"getAddress(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001233 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001234 }
1235
Svet Ganov408abf72015-05-12 19:13:36 -07001236 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS)
1237 != PackageManager.PERMISSION_GRANTED) {
1238 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
1239 }
1240
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001241 try {
1242 mBluetoothLock.readLock().lock();
1243 if (mBluetooth != null) return mBluetooth.getAddress();
1244 } catch (RemoteException e) {
1245 Slog.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e);
1246 } finally {
1247 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001248 }
Ajay Panickerbf796d82016-03-11 13:47:20 -08001249
Matthew Xiecdce0b92012-07-12 19:06:15 -07001250 // mAddress is accessed from outside.
1251 // It is alright without a lock. Here, bluetooth is off, no other thread is
1252 // changing mAddress
fredc0f420372012-04-12 00:02:00 -07001253 return mAddress;
1254 }
fredc649fe492012-04-19 01:07:18 -07001255
fredc0f420372012-04-12 00:02:00 -07001256 public String getName() {
Matthew Xieaf5ddbf2012-12-04 10:47:43 -08001257 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
1258 "Need BLUETOOTH permission");
Zhihai Xu40874a02012-10-08 17:57:03 -07001259
Zhihai Xu6eb76522012-11-29 15:41:04 -08001260 if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
1261 (!checkIfCallerIsForegroundUser())) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001262 Slog.w(TAG,"getName(): not allowed for non-active and non system user");
Zhihai Xu6eb76522012-11-29 15:41:04 -08001263 return null;
Zhihai Xu40874a02012-10-08 17:57:03 -07001264 }
1265
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001266 try {
1267 mBluetoothLock.readLock().lock();
1268 if (mBluetooth != null) return mBluetooth.getName();
1269 } catch (RemoteException e) {
1270 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
1271 } finally {
1272 mBluetoothLock.readLock().unlock();
fredc116d1d462012-04-20 14:47:08 -07001273 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001274
Matthew Xiecdce0b92012-07-12 19:06:15 -07001275 // mName is accessed from outside.
1276 // It alright without a lock. Here, bluetooth is off, no other thread is
1277 // changing mName
fredc0f420372012-04-12 00:02:00 -07001278 return mName;
1279 }
1280
fredc0f420372012-04-12 00:02:00 -07001281 private class BluetoothServiceConnection implements ServiceConnection {
Marie Janssencb21ad72016-12-13 10:51:02 -08001282 public void onServiceConnected(ComponentName componentName, IBinder service) {
1283 String name = componentName.getClassName();
1284 if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name);
fredc0f420372012-04-12 00:02:00 -07001285 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001286 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001287 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001288 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001289 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1290 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001291 Slog.e(TAG, "Unknown service connected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001292 return;
1293 }
fredc0f420372012-04-12 00:02:00 -07001294 msg.obj = service;
1295 mHandler.sendMessage(msg);
1296 }
1297
Marie Janssencb21ad72016-12-13 10:51:02 -08001298 public void onServiceDisconnected(ComponentName componentName) {
1299 // Called if we unexpectedly disconnect.
1300 String name = componentName.getClassName();
1301 if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name);
fredc0f420372012-04-12 00:02:00 -07001302 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
Marie Janssencb21ad72016-12-13 10:51:02 -08001303 if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001304 msg.arg1 = SERVICE_IBLUETOOTH;
Marie Janssencb21ad72016-12-13 10:51:02 -08001305 } else if (name.equals("com.android.bluetooth.gatt.GattService")) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001306 msg.arg1 = SERVICE_IBLUETOOTHGATT;
1307 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001308 Slog.e(TAG, "Unknown service disconnected: " + name);
Matthew Xieddf7e472013-03-01 18:41:02 -08001309 return;
1310 }
fredc0f420372012-04-12 00:02:00 -07001311 mHandler.sendMessage(msg);
1312 }
1313 }
1314
1315 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
1316
Zhihai Xu40874a02012-10-08 17:57:03 -07001317 private class BluetoothHandler extends Handler {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001318 boolean mGetNameAddressOnly = false;
1319
Zhihai Xu40874a02012-10-08 17:57:03 -07001320 public BluetoothHandler(Looper looper) {
1321 super(looper);
1322 }
1323
fredc0f420372012-04-12 00:02:00 -07001324 @Override
1325 public void handleMessage(Message msg) {
fredc0f420372012-04-12 00:02:00 -07001326 switch (msg.what) {
Ajay Panicker4bb48302016-03-31 14:14:27 -07001327 case MESSAGE_GET_NAME_AND_ADDRESS:
1328 if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001329 try {
1330 mBluetoothLock.writeLock().lock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001331 if ((mBluetooth == null) && (!mBinding)) {
1332 if (DBG) Slog.d(TAG, "Binding to service to get name and address");
1333 mGetNameAddressOnly = true;
1334 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1335 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
1336 Intent i = new Intent(IBluetooth.class.getName());
1337 if (!doBind(i, mConnection,
1338 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1339 UserHandle.CURRENT)) {
1340 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
1341 } else {
1342 mBinding = true;
1343 }
1344 } else if (mBluetooth != null) {
1345 try {
1346 storeNameAndAddress(mBluetooth.getName(),
1347 mBluetooth.getAddress());
1348 } catch (RemoteException re) {
1349 Slog.e(TAG, "Unable to grab names", re);
1350 }
1351 if (mGetNameAddressOnly && !mEnable) {
1352 unbindAndFinish();
1353 }
1354 mGetNameAddressOnly = false;
1355 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001356 } finally {
1357 mBluetoothLock.writeLock().unlock();
Ajay Panicker4bb48302016-03-31 14:14:27 -07001358 }
1359 break;
1360
Matthew Xiecdce0b92012-07-12 19:06:15 -07001361 case MESSAGE_ENABLE:
fredcf2458862012-04-16 15:18:27 -07001362 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001363 Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
fredc649fe492012-04-19 01:07:18 -07001364 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001365 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1366 mEnable = true;
Calvin Ona0b91d72016-06-15 17:58:23 -07001367
1368 // Use service interface to get the exact state
1369 try {
1370 mBluetoothLock.readLock().lock();
1371 if (mBluetooth != null) {
1372 int state = mBluetooth.getState();
1373 if (state == BluetoothAdapter.STATE_BLE_ON) {
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001374 Slog.w(TAG, "BT Enable in BLE_ON State, going to ON");
Calvin Ona0b91d72016-06-15 17:58:23 -07001375 mBluetooth.onLeServiceUp();
Marie Janssene0bfa2e2016-12-20 11:21:12 -08001376 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
Calvin Ona0b91d72016-06-15 17:58:23 -07001377 break;
1378 }
1379 }
1380 } catch (RemoteException e) {
1381 Slog.e(TAG, "", e);
1382 } finally {
1383 mBluetoothLock.readLock().unlock();
1384 }
1385
1386 mQuietEnable = (msg.arg1 == 1);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001387 if (mBluetooth == null) {
Calvin Ona0b91d72016-06-15 17:58:23 -07001388 handleEnable(mQuietEnable);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001389 } else {
1390 //
1391 // We need to wait until transitioned to STATE_OFF and
1392 // the previous Bluetooth process has exited. The
1393 // waiting period has three components:
1394 // (a) Wait until the local state is STATE_OFF. This
1395 // is accomplished by "waitForOnOff(false, true)".
1396 // (b) Wait until the STATE_OFF state is updated to
1397 // all components.
1398 // (c) Wait until the Bluetooth process exits, and
1399 // ActivityManager detects it.
1400 // The waiting for (b) and (c) is accomplished by
1401 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
1402 // message. On slower devices, that delay needs to be
1403 // on the order of (2 * SERVICE_RESTART_TIME_MS).
1404 //
1405 waitForOnOff(false, true);
Pavlin Radoslavove47ec142016-06-01 22:25:18 -07001406 Message restartMsg = mHandler.obtainMessage(
1407 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1408 mHandler.sendMessageDelayed(restartMsg,
1409 2 * SERVICE_RESTART_TIME_MS);
1410 }
fredc649fe492012-04-19 01:07:18 -07001411 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001412
fredc0f420372012-04-12 00:02:00 -07001413 case MESSAGE_DISABLE:
Marie Janssencb21ad72016-12-13 10:51:02 -08001414 if (DBG) Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
Zhihai Xu40874a02012-10-08 17:57:03 -07001415 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
1416 if (mEnable && mBluetooth != null) {
1417 waitForOnOff(true, false);
1418 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001419 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001420 waitForOnOff(false, false);
1421 } else {
1422 mEnable = false;
Zhihai Xu401202b2012-12-03 11:36:21 -08001423 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001424 }
fredc0f420372012-04-12 00:02:00 -07001425 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001426
fredc0f420372012-04-12 00:02:00 -07001427 case MESSAGE_REGISTER_ADAPTER:
1428 {
1429 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001430 mCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001431 break;
Marie Janssencb21ad72016-12-13 10:51:02 -08001432 }
fredc0f420372012-04-12 00:02:00 -07001433 case MESSAGE_UNREGISTER_ADAPTER:
1434 {
1435 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001436 mCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001437 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001438 }
fredc0f420372012-04-12 00:02:00 -07001439 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
1440 {
1441 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001442 mStateChangeCallbacks.register(callback);
fredc0f420372012-04-12 00:02:00 -07001443 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001444 }
fredc0f420372012-04-12 00:02:00 -07001445 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK:
1446 {
1447 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
Marie Janssencb21ad72016-12-13 10:51:02 -08001448 mStateChangeCallbacks.unregister(callback);
fredc0f420372012-04-12 00:02:00 -07001449 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001450 }
Benjamin Franze8b98922014-11-12 15:57:54 +00001451 case MESSAGE_ADD_PROXY_DELAYED:
1452 {
1453 ProfileServiceConnections psc = mProfileServices.get(
1454 new Integer(msg.arg1));
1455 if (psc == null) {
1456 break;
1457 }
1458 IBluetoothProfileServiceConnection proxy =
1459 (IBluetoothProfileServiceConnection) msg.obj;
1460 psc.addProxy(proxy);
1461 break;
1462 }
1463 case MESSAGE_BIND_PROFILE_SERVICE:
1464 {
1465 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj;
1466 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj);
1467 if (psc == null) {
1468 break;
1469 }
1470 psc.bindService();
1471 break;
1472 }
fredc0f420372012-04-12 00:02:00 -07001473 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
1474 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001475 if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
fredc0f420372012-04-12 00:02:00 -07001476
1477 IBinder service = (IBinder) msg.obj;
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001478 try {
1479 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001480 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001481 mBluetoothGatt = IBluetoothGatt.Stub
1482 .asInterface(Binder.allowBlocking(service));
Nitin Arorad055adb2015-03-02 15:03:51 -08001483 onBluetoothGattServiceUp();
Matthew Xieddf7e472013-03-01 18:41:02 -08001484 break;
1485 } // else must be SERVICE_IBLUETOOTH
1486
1487 //Remove timeout
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001488 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Matthew Xieddf7e472013-03-01 18:41:02 -08001489
fredc0f420372012-04-12 00:02:00 -07001490 mBinding = false;
Marie Janssen9db28eb2016-01-12 16:05:15 -08001491 mBluetoothBinder = service;
Jeff Sharkey0a17db12016-11-04 11:23:46 -06001492 mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
fredc0f420372012-04-12 00:02:00 -07001493
Ajay Panicker4bb48302016-03-31 14:14:27 -07001494 if (!isNameAndAddressSet()) {
1495 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
1496 mHandler.sendMessage(getMsg);
1497 if (mGetNameAddressOnly) return;
1498 }
1499
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001500 try {
1501 boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
1502 Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
1503 if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001504 Slog.e(TAG,"IBluetooth.configHciSnoopLog return false");
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001505 }
1506 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001507 Slog.e(TAG,"Unable to call configHciSnoopLog", e);
Zhihai Xuaf5971e2013-06-10 20:28:31 -07001508 }
1509
Matthew Xiecdce0b92012-07-12 19:06:15 -07001510 //Register callback object
fredcbf072a72012-05-09 16:52:50 -07001511 try {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001512 mBluetooth.registerCallback(mBluetoothCallback);
1513 } catch (RemoteException re) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001514 Slog.e(TAG, "Unable to register BluetoothCallback",re);
fredcbf072a72012-05-09 16:52:50 -07001515 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001516 //Inform BluetoothAdapter instances that service is up
Zhihai Xu40874a02012-10-08 17:57:03 -07001517 sendBluetoothServiceUpCallback();
1518
Matthew Xiecdce0b92012-07-12 19:06:15 -07001519 //Do enable request
1520 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001521 if (mQuietEnable == false) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001522 if (!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001523 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001524 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001525 } else {
1526 if (!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001527 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001528 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001529 }
1530 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001531 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001532 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001533 } finally {
1534 mBluetoothLock.writeLock().unlock();
Freda8c6df02012-07-11 10:25:23 -07001535 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001536
1537 if (!mEnable) {
1538 waitForOnOff(true, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001539 handleDisable();
Zhihai Xu40874a02012-10-08 17:57:03 -07001540 waitForOnOff(false, false);
1541 }
fredc649fe492012-04-19 01:07:18 -07001542 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001543 }
fredcbf072a72012-05-09 16:52:50 -07001544 case MESSAGE_BLUETOOTH_STATE_CHANGE:
fredc0f420372012-04-12 00:02:00 -07001545 {
fredcbf072a72012-05-09 16:52:50 -07001546 int prevState = msg.arg1;
1547 int newState = msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001548 if (DBG) {
1549 Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(prevState) + " > " +
1550 BluetoothAdapter.nameForState(newState));
1551 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001552 mState = newState;
1553 bluetoothStateChangeHandler(prevState, newState);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001554 // handle error state transition case from TURNING_ON to OFF
1555 // unbind and rebind bluetooth service and enable bluetooth
Nitin Arorad055adb2015-03-02 15:03:51 -08001556 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001557 (newState == BluetoothAdapter.STATE_OFF) &&
1558 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001559 recoverBluetoothServiceFromError(false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001560 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001561 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
Calvin Ona0b91d72016-06-15 17:58:23 -07001562 (newState == BluetoothAdapter.STATE_BLE_ON) &&
1563 (mBluetooth != null) && mEnable) {
Marie Janssen2977c3e2016-11-09 12:01:24 -08001564 recoverBluetoothServiceFromError(true);
Nitin Arorad055adb2015-03-02 15:03:51 -08001565 }
Calvin Ona0b91d72016-06-15 17:58:23 -07001566 // If we tried to enable BT while BT was in the process of shutting down,
1567 // wait for the BT process to fully tear down and then force a restart
1568 // here. This is a bit of a hack (b/29363429).
1569 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) &&
1570 (newState == BluetoothAdapter.STATE_OFF)) {
1571 if (mEnable) {
1572 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
1573 waitForOnOff(false, true);
1574 Message restartMsg = mHandler.obtainMessage(
1575 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1576 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
1577 }
1578 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001579 if (newState == BluetoothAdapter.STATE_ON ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001580 newState == BluetoothAdapter.STATE_BLE_ON) {
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001581 // bluetooth is working, reset the counter
1582 if (mErrorRecoveryRetryCounter != 0) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001583 Slog.w(TAG, "bluetooth is recovered from error");
Zhihai Xudd9d17d2013-01-08 17:05:58 -08001584 mErrorRecoveryRetryCounter = 0;
1585 }
1586 }
fredc649fe492012-04-19 01:07:18 -07001587 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001588 }
fredc0f420372012-04-12 00:02:00 -07001589 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
1590 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001591 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001592 try {
1593 mBluetoothLock.writeLock().lock();
Matthew Xieddf7e472013-03-01 18:41:02 -08001594 if (msg.arg1 == SERVICE_IBLUETOOTH) {
1595 // if service is unbinded already, do nothing and return
1596 if (mBluetooth == null) break;
1597 mBluetooth = null;
1598 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
1599 mBluetoothGatt = null;
1600 break;
1601 } else {
Marie Janssencb21ad72016-12-13 10:51:02 -08001602 Slog.e(TAG, "Unknown argument for service disconnect!");
Matthew Xieddf7e472013-03-01 18:41:02 -08001603 break;
1604 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001605 } finally {
1606 mBluetoothLock.writeLock().unlock();
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301607 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001608
Marie Janssene54b4222017-03-16 18:10:59 -07001609 // log the unexpected crash
1610 addCrashLog();
1611 addActiveLog(REASON_UNEXPECTED, false);
Zhihai Xu40874a02012-10-08 17:57:03 -07001612 if (mEnable) {
1613 mEnable = false;
1614 // Send a Bluetooth Restart message
1615 Message restartMsg = mHandler.obtainMessage(
1616 MESSAGE_RESTART_BLUETOOTH_SERVICE);
1617 mHandler.sendMessageDelayed(restartMsg,
1618 SERVICE_RESTART_TIME_MS);
1619 }
1620
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001621 sendBluetoothServiceDownCallback();
Zhihai Xu40874a02012-10-08 17:57:03 -07001622
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001623 // Send BT state broadcast to update
1624 // the BT icon correctly
1625 if ((mState == BluetoothAdapter.STATE_TURNING_ON) ||
Calvin Ona0b91d72016-06-15 17:58:23 -07001626 (mState == BluetoothAdapter.STATE_ON)) {
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001627 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1628 BluetoothAdapter.STATE_TURNING_OFF);
1629 mState = BluetoothAdapter.STATE_TURNING_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001630 }
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001631 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1632 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
1633 BluetoothAdapter.STATE_OFF);
1634 }
1635
1636 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1637 mState = BluetoothAdapter.STATE_OFF;
fredc649fe492012-04-19 01:07:18 -07001638 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001639 }
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301640 case MESSAGE_RESTART_BLUETOOTH_SERVICE:
1641 {
Marie Janssencb21ad72016-12-13 10:51:02 -08001642 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301643 /* Enable without persisting the setting as
1644 it doesnt change when IBluetooth
1645 service restarts */
Zhihai Xu40874a02012-10-08 17:57:03 -07001646 mEnable = true;
Marie Janssene54b4222017-03-16 18:10:59 -07001647 addActiveLog(REASON_RESTARTED, true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001648 handleEnable(mQuietEnable);
Syed Ibrahim M1223e5a2012-08-29 18:07:26 +05301649 break;
1650 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001651 case MESSAGE_TIMEOUT_BIND: {
1652 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND");
1653 mBluetoothLock.writeLock().lock();
1654 mBinding = false;
1655 mBluetoothLock.writeLock().unlock();
1656 break;
1657 }
fredc0f420372012-04-12 00:02:00 -07001658 case MESSAGE_TIMEOUT_UNBIND:
1659 {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001660 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001661 mBluetoothLock.writeLock().lock();
1662 mUnbinding = false;
1663 mBluetoothLock.writeLock().unlock();
fredc649fe492012-04-19 01:07:18 -07001664 break;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001665 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001666
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001667 case MESSAGE_USER_SWITCHED: {
1668 if (DBG) Slog.d(TAG, "MESSAGE_USER_SWITCHED");
Zhihai Xu40874a02012-10-08 17:57:03 -07001669 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001670
Zhihai Xu40874a02012-10-08 17:57:03 -07001671 /* disable and enable BT when detect a user switch */
1672 if (mEnable && mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001673 try {
1674 mBluetoothLock.readLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001675 if (mBluetooth != null) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001676 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xu40874a02012-10-08 17:57:03 -07001677 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001678 } catch (RemoteException re) {
1679 Slog.e(TAG, "Unable to unregister", re);
1680 } finally {
1681 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001682 }
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001683
1684 if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
1685 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE
1686 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF);
1687 mState = BluetoothAdapter.STATE_OFF;
1688 }
1689 if (mState == BluetoothAdapter.STATE_OFF) {
1690 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON);
1691 mState = BluetoothAdapter.STATE_TURNING_ON;
1692 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001693
1694 waitForOnOff(true, false);
1695
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001696 if (mState == BluetoothAdapter.STATE_TURNING_ON) {
1697 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
1698 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001699
Benjamin Franze8b98922014-11-12 15:57:54 +00001700 unbindAllBluetoothProfileServices();
Zhihai Xu40874a02012-10-08 17:57:03 -07001701 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07001702 addActiveLog(REASON_USER_SWITCH, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001703 handleDisable();
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001704 // Pbap service need receive STATE_TURNING_OFF intent to close
1705 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
1706 BluetoothAdapter.STATE_TURNING_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001707
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001708 boolean didDisableTimeout = !waitForOnOff(false, true);
Zhihai Xu40874a02012-10-08 17:57:03 -07001709
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001710 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
Zhihai Xu40874a02012-10-08 17:57:03 -07001711 BluetoothAdapter.STATE_OFF);
Zhihai Xu40874a02012-10-08 17:57:03 -07001712 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001713
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07001714 try {
1715 mBluetoothLock.writeLock().lock();
1716 if (mBluetooth != null) {
1717 mBluetooth = null;
1718 // Unbind
1719 mContext.unbindService(mConnection);
1720 }
1721 mBluetoothGatt = null;
1722 } finally {
1723 mBluetoothLock.writeLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001724 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001725
Pavlin Radoslavov41401112016-06-27 15:25:18 -07001726 //
1727 // If disabling Bluetooth times out, wait for an
1728 // additional amount of time to ensure the process is
1729 // shut down completely before attempting to restart.
1730 //
1731 if (didDisableTimeout) {
1732 SystemClock.sleep(3000);
1733 } else {
1734 SystemClock.sleep(100);
1735 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001736
Zhihai Xu4e22ad32012-11-13 15:11:26 -08001737 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
1738 mState = BluetoothAdapter.STATE_OFF;
Zhihai Xu40874a02012-10-08 17:57:03 -07001739 // enable
Marie Janssene54b4222017-03-16 18:10:59 -07001740 addActiveLog(REASON_USER_SWITCH, true);
Zhihai Xu401202b2012-12-03 11:36:21 -08001741 handleEnable(mQuietEnable);
John Spurlock8a985d22014-02-25 09:40:05 -05001742 } else if (mBinding || mBluetooth != null) {
Zhihai Xu40874a02012-10-08 17:57:03 -07001743 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
1744 userMsg.arg2 = 1 + msg.arg2;
Marie Janssencb21ad72016-12-13 10:51:02 -08001745 // if user is switched when service is binding retry after a delay
Zhihai Xu40874a02012-10-08 17:57:03 -07001746 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS);
1747 if (DBG) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001748 Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2);
Zhihai Xu40874a02012-10-08 17:57:03 -07001749 }
John Spurlock8a985d22014-02-25 09:40:05 -05001750 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001751 break;
1752 }
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001753 case MESSAGE_USER_UNLOCKED: {
1754 if (DBG) Slog.d(TAG, "MESSAGE_USER_UNLOCKED");
1755 mHandler.removeMessages(MESSAGE_USER_SWITCHED);
1756
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001757 if (mEnable && !mBinding && (mBluetooth == null)) {
1758 // We should be connected, but we gave up for some
1759 // reason; maybe the Bluetooth service wasn't encryption
1760 // aware, so try binding again.
1761 if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock");
1762 handleEnable(mQuietEnable);
Jeff Sharkeyaacb89e2016-03-05 14:42:58 -07001763 }
1764 }
fredc0f420372012-04-12 00:02:00 -07001765 }
1766 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001767 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001768
Zhihai Xu401202b2012-12-03 11:36:21 -08001769 private void handleEnable(boolean quietMode) {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001770 mQuietEnable = quietMode;
1771
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001772 try {
1773 mBluetoothLock.writeLock().lock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001774 if ((mBluetooth == null) && (!mBinding)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001775 //Start bind timeout and bind
1776 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
1777 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001778 Intent i = new Intent(IBluetooth.class.getName());
Dianne Hackbornce09f5a2014-10-10 15:03:13 -07001779 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
1780 UserHandle.CURRENT)) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001781 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Zhihai Xu40874a02012-10-08 17:57:03 -07001782 } else {
1783 mBinding = true;
Matthew Xiecdce0b92012-07-12 19:06:15 -07001784 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001785 } else if (mBluetooth != null) {
Matthew Xiecdce0b92012-07-12 19:06:15 -07001786 //Enable bluetooth
1787 try {
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001788 if (!mQuietEnable) {
1789 if(!mBluetooth.enable()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001790 Slog.e(TAG,"IBluetooth.enable() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001791 }
1792 }
1793 else {
1794 if(!mBluetooth.enableNoAutoConnect()) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001795 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
Ganesh Ganapathi Battafffa86b2012-08-08 15:35:49 -07001796 }
Matthew Xiecdce0b92012-07-12 19:06:15 -07001797 }
1798 } catch (RemoteException e) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001799 Slog.e(TAG,"Unable to call enable()",e);
Matthew Xiecdce0b92012-07-12 19:06:15 -07001800 }
1801 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001802 } finally {
1803 mBluetoothLock.writeLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001804 }
1805 }
1806
Dianne Hackborn221ea892013-08-04 16:50:16 -07001807 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
1808 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
1809 intent.setComponent(comp);
1810 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001811 Slog.e(TAG, "Fail to bind to: " + intent);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001812 return false;
1813 }
1814 return true;
1815 }
1816
Zhihai Xu401202b2012-12-03 11:36:21 -08001817 private void handleDisable() {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001818 try {
1819 mBluetoothLock.readLock().lock();
Andre Eisenbach305fdab2015-11-11 21:43:26 -08001820 if (mBluetooth != null) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001821 if (DBG) Slog.d(TAG,"Sending off request.");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001822 if (!mBluetooth.disable()) {
1823 Slog.e(TAG,"IBluetooth.disable() returned false");
Matthew Xiecdce0b92012-07-12 19:06:15 -07001824 }
1825 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001826 } catch (RemoteException e) {
1827 Slog.e(TAG,"Unable to call disable()",e);
1828 } finally {
1829 mBluetoothLock.readLock().unlock();
Matthew Xiecdce0b92012-07-12 19:06:15 -07001830 }
1831 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001832
1833 private boolean checkIfCallerIsForegroundUser() {
1834 int foregroundUser;
1835 int callingUser = UserHandle.getCallingUserId();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001836 int callingUid = Binder.getCallingUid();
Zhihai Xu40874a02012-10-08 17:57:03 -07001837 long callingIdentity = Binder.clearCallingIdentity();
Benjamin Franze8b98922014-11-12 15:57:54 +00001838 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1839 UserInfo ui = um.getProfileParent(callingUser);
1840 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001841 int callingAppId = UserHandle.getAppId(callingUid);
Zhihai Xu40874a02012-10-08 17:57:03 -07001842 boolean valid = false;
1843 try {
1844 foregroundUser = ActivityManager.getCurrentUser();
Martijn Coenen8385c5a2012-11-29 10:14:16 -08001845 valid = (callingUser == foregroundUser) ||
Benjamin Franze8b98922014-11-12 15:57:54 +00001846 parentUser == foregroundUser ||
Adrian Roosbd9a9a52014-08-18 15:31:57 +02001847 callingAppId == Process.NFC_UID ||
1848 callingAppId == mSystemUiUid;
Marie Janssencb21ad72016-12-13 10:51:02 -08001849 if (DBG && !valid) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07001850 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid
Zhihai Xu40874a02012-10-08 17:57:03 -07001851 + " callingUser=" + callingUser
Benjamin Franze8b98922014-11-12 15:57:54 +00001852 + " parentUser=" + parentUser
Zhihai Xu40874a02012-10-08 17:57:03 -07001853 + " foregroundUser=" + foregroundUser);
1854 }
1855 } finally {
1856 Binder.restoreCallingIdentity(callingIdentity);
1857 }
1858 return valid;
1859 }
1860
Nitin Arorad055adb2015-03-02 15:03:51 -08001861 private void sendBleStateChanged(int prevState, int newState) {
Marie Janssencb21ad72016-12-13 10:51:02 -08001862 if (DBG) Slog.d(TAG,"Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) +
1863 " > " + BluetoothAdapter.nameForState(newState));
Nitin Arorad055adb2015-03-02 15:03:51 -08001864 // Send broadcast message to everyone else
1865 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
1866 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1867 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1868 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1869 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
1870 }
1871
Zhihai Xu40874a02012-10-08 17:57:03 -07001872 private void bluetoothStateChangeHandler(int prevState, int newState) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001873 boolean isStandardBroadcast = true;
Marie Janssencb21ad72016-12-13 10:51:02 -08001874 if (prevState == newState) { // No change. Nothing to do.
1875 return;
1876 }
1877 // Notify all proxy objects first of adapter state change
1878 if (newState == BluetoothAdapter.STATE_BLE_ON ||
1879 newState == BluetoothAdapter.STATE_OFF) {
1880 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF
1881 && newState == BluetoothAdapter.STATE_BLE_ON);
Zhihai Xu40874a02012-10-08 17:57:03 -07001882
Marie Janssencb21ad72016-12-13 10:51:02 -08001883 if (newState == BluetoothAdapter.STATE_OFF) {
1884 // If Bluetooth is off, send service down event to proxy objects, and unbind
1885 if (DBG) Slog.d(TAG, "Bluetooth is complete send Service Down");
1886 sendBluetoothServiceDownCallback();
1887 unbindAndFinish();
Nitin Arorad055adb2015-03-02 15:03:51 -08001888 sendBleStateChanged(prevState, newState);
Marie Janssencb21ad72016-12-13 10:51:02 -08001889 // Don't broadcast as it has already been broadcast before
Nitin Arorad055adb2015-03-02 15:03:51 -08001890 isStandardBroadcast = false;
1891
Marie Janssencb21ad72016-12-13 10:51:02 -08001892 } else if (!intermediate_off) {
1893 // connect to GattService
1894 if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode");
1895 if (mBluetoothGatt != null) {
1896 if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp");
1897 onBluetoothGattServiceUp();
1898 } else {
1899 if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service");
1900 if (mContext.getPackageManager().hasSystemFeature(
1901 PackageManager.FEATURE_BLUETOOTH_LE)) {
1902 Intent i = new Intent(IBluetoothGatt.class.getName());
1903 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT);
1904 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001905 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001906 sendBleStateChanged(prevState, newState);
1907 //Don't broadcase this as std intent
1908 isStandardBroadcast = false;
1909
1910 } else if (intermediate_off) {
1911 if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode");
1912 // For LE only mode, broadcast as is
1913 sendBleStateChanged(prevState, newState);
1914 sendBluetoothStateCallback(false); // BT is OFF for general users
1915 // Broadcast as STATE_OFF
1916 newState = BluetoothAdapter.STATE_OFF;
1917 sendBrEdrDownCallback();
Nitin Arorad055adb2015-03-02 15:03:51 -08001918 }
Marie Janssencb21ad72016-12-13 10:51:02 -08001919 } else if (newState == BluetoothAdapter.STATE_ON) {
1920 boolean isUp = (newState == BluetoothAdapter.STATE_ON);
1921 sendBluetoothStateCallback(isUp);
1922 sendBleStateChanged(prevState, newState);
1923
1924 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON ||
1925 newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) {
1926 sendBleStateChanged(prevState, newState);
1927 isStandardBroadcast = false;
1928
1929 } else if (newState == BluetoothAdapter.STATE_TURNING_ON ||
1930 newState == BluetoothAdapter.STATE_TURNING_OFF) {
1931 sendBleStateChanged(prevState, newState);
1932 }
1933
1934 if (isStandardBroadcast) {
1935 if (prevState == BluetoothAdapter.STATE_BLE_ON) {
1936 // Show prevState of BLE_ON as OFF to standard users
1937 prevState = BluetoothAdapter.STATE_OFF;
1938 }
1939 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
1940 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
1941 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
1942 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1943 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM);
Zhihai Xu40874a02012-10-08 17:57:03 -07001944 }
1945 }
1946
1947 /**
1948 * if on is true, wait for state become ON
1949 * if off is true, wait for state become OFF
1950 * if both on and off are false, wait for state not ON
1951 */
1952 private boolean waitForOnOff(boolean on, boolean off) {
1953 int i = 0;
1954 while (i < 10) {
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001955 try {
1956 mBluetoothLock.readLock().lock();
1957 if (mBluetooth == null) break;
1958 if (on) {
1959 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true;
1960 } else if (off) {
1961 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true;
1962 } else {
1963 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true;
Zhihai Xu40874a02012-10-08 17:57:03 -07001964 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07001965 } catch (RemoteException e) {
1966 Slog.e(TAG, "getState()", e);
1967 break;
1968 } finally {
1969 mBluetoothLock.readLock().unlock();
Zhihai Xu40874a02012-10-08 17:57:03 -07001970 }
1971 if (on || off) {
1972 SystemClock.sleep(300);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07001973 } else {
Zhihai Xu40874a02012-10-08 17:57:03 -07001974 SystemClock.sleep(50);
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07001975 }
Zhihai Xu40874a02012-10-08 17:57:03 -07001976 i++;
1977 }
Jeff Sharkey67609c72016-03-05 14:29:13 -07001978 Slog.e(TAG,"waitForOnOff time out");
Zhihai Xu40874a02012-10-08 17:57:03 -07001979 return false;
1980 }
Zhihai Xu681ae7f2012-11-12 15:14:18 -08001981
Marie Janssen59804562016-12-28 14:13:21 -08001982 private void sendDisableMsg(String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08001983 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE));
Marie Janssen59804562016-12-28 14:13:21 -08001984 addActiveLog(packageName, false);
Zhihai Xu401202b2012-12-03 11:36:21 -08001985 }
1986
Marie Janssen59804562016-12-28 14:13:21 -08001987 private void sendEnableMsg(boolean quietMode, String packageName) {
Zhihai Xu401202b2012-12-03 11:36:21 -08001988 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
1989 quietMode ? 1 : 0, 0));
Marie Janssen59804562016-12-28 14:13:21 -08001990 addActiveLog(packageName, true);
1991 }
1992
1993 private void addActiveLog(String packageName, boolean enable) {
1994 synchronized (mActiveLogs) {
Marie Janssene54b4222017-03-16 18:10:59 -07001995 if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
Marie Janssen59804562016-12-28 14:13:21 -08001996 mActiveLogs.remove();
1997 }
1998 mActiveLogs.add(new ActiveLog(packageName, enable, System.currentTimeMillis()));
1999 }
Zhihai Xu401202b2012-12-03 11:36:21 -08002000 }
2001
Marie Janssene54b4222017-03-16 18:10:59 -07002002 private void addCrashLog() {
2003 synchronized (mCrashTimestamps) {
2004 if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) mCrashTimestamps.removeFirst();
2005 mCrashTimestamps.add(System.currentTimeMillis());
2006 mCrashes++;
2007 }
2008 }
2009
Marie Janssen2977c3e2016-11-09 12:01:24 -08002010 private void recoverBluetoothServiceFromError(boolean clearBle) {
Jeff Sharkey67609c72016-03-05 14:29:13 -07002011 Slog.e(TAG,"recoverBluetoothServiceFromError");
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002012 try {
2013 mBluetoothLock.readLock().lock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002014 if (mBluetooth != null) {
2015 //Unregister callback object
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002016 mBluetooth.unregisterCallback(mBluetoothCallback);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002017 }
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002018 } catch (RemoteException re) {
2019 Slog.e(TAG, "Unable to unregister", re);
2020 } finally {
2021 mBluetoothLock.readLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002022 }
2023
2024 SystemClock.sleep(500);
2025
2026 // disable
Marie Janssene54b4222017-03-16 18:10:59 -07002027 addActiveLog(REASON_START_CRASH, false);
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002028 handleDisable();
2029
2030 waitForOnOff(false, true);
2031
2032 sendBluetoothServiceDownCallback();
Pavlin Radoslavoveb50a392016-05-22 22:16:41 -07002033
Pavlin Radoslavove957a8a2016-05-24 15:28:41 -07002034 try {
2035 mBluetoothLock.writeLock().lock();
2036 if (mBluetooth != null) {
2037 mBluetooth = null;
2038 // Unbind
2039 mContext.unbindService(mConnection);
2040 }
2041 mBluetoothGatt = null;
2042 } finally {
2043 mBluetoothLock.writeLock().unlock();
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002044 }
2045
2046 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
2047 mState = BluetoothAdapter.STATE_OFF;
2048
Marie Janssen2977c3e2016-11-09 12:01:24 -08002049 if (clearBle) {
2050 clearBleApps();
2051 }
2052
Zhihai Xudd9d17d2013-01-08 17:05:58 -08002053 mEnable = false;
2054
2055 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
2056 // Send a Bluetooth Restart message to reenable bluetooth
2057 Message restartMsg = mHandler.obtainMessage(
2058 MESSAGE_RESTART_BLUETOOTH_SERVICE);
2059 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
2060 } else {
2061 // todo: notify user to power down and power up phone to make bluetooth work.
2062 }
2063 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002064
Lenka Trochtova63d5e4a72016-12-02 12:19:39 +01002065 private boolean isBluetoothDisallowed() {
2066 long callingIdentity = Binder.clearCallingIdentity();
2067 try {
2068 return mContext.getSystemService(UserManager.class)
2069 .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
2070 } finally {
2071 Binder.restoreCallingIdentity(callingIdentity);
2072 }
2073 }
2074
Lenka Trochtovac6f0e232017-01-17 10:35:49 +01002075 /**
2076 * Disables BluetoothOppLauncherActivity component, so the Bluetooth sharing option is not
2077 * offered to the user if Bluetooth is disallowed. Puts the component to its default state if
2078 * Bluetooth is not disallowed.
2079 *
2080 * @param bluetoothDisallowed whether the {@link UserManager.DISALLOW_BLUETOOTH} user
2081 * restriction was set.
2082 */
2083 private void updateOppLauncherComponentState(boolean bluetoothDisallowed) {
2084 final ComponentName oppLauncherComponent = new ComponentName("com.android.bluetooth",
2085 "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
2086 final int newState = bluetoothDisallowed
2087 ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
2088 : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2089 try {
2090 mContext.getPackageManager()
2091 .setComponentEnabledSetting(oppLauncherComponent, newState, 0);
2092 } catch (Exception e) {
2093 // The component was not found, do nothing.
2094 }
2095 }
2096
Mike Lockwood726d4de2014-10-28 14:06:28 -07002097 @Override
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002098 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002099 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002100 String errorMsg = null;
Marie Janssen59804562016-12-28 14:13:21 -08002101
2102 boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
2103
2104 if (!protoOut) {
2105 writer.println("Bluetooth Status");
2106 writer.println(" enabled: " + isEnabled());
2107 writer.println(" state: " + BluetoothAdapter.nameForState(mState));
2108 writer.println(" address: " + mAddress);
2109 writer.println(" name: " + mName);
2110 if (mEnable) {
2111 long onDuration = System.currentTimeMillis() - mActiveLogs.getLast().getTime();
2112 String onDurationString = String.format("%02d:%02d:%02d.%03d",
2113 (int)(onDuration / (1000 * 60 * 60)),
2114 (int)((onDuration / (1000 * 60)) % 60),
2115 (int)((onDuration / 1000) % 60),
2116 (int)(onDuration % 1000));
2117 writer.println(" time since enabled: " + onDurationString + "\n");
2118 }
2119
Marie Janssena95924d2017-01-18 09:37:52 -08002120 if (mActiveLogs.size() == 0) {
2121 writer.println("Bluetooth never enabled!");
2122 } else {
2123 writer.println("Enable log:");
2124 for (ActiveLog log : mActiveLogs) {
2125 writer.println(" " + log);
2126 }
Marie Janssen59804562016-12-28 14:13:21 -08002127 }
2128
Marie Janssene54b4222017-03-16 18:10:59 -07002129 writer.println("Bluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
2130 if (mCrashes == CRASH_LOG_MAX_SIZE) writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
2131 for (Long time : mCrashTimestamps) {
2132 writer.println(" " + timeToLog(time.longValue()));
2133 }
2134
Marie Janssena95924d2017-01-18 09:37:52 -08002135 String bleAppString = "No BLE Apps registered.";
2136 if (mBleApps.size() == 1) {
2137 bleAppString = "1 BLE App registered:";
2138 } else if (mBleApps.size() > 1) {
2139 bleAppString = mBleApps.size() + " BLE Apps registered:";
2140 }
2141 writer.println("\n" + bleAppString);
Marie Janssen59804562016-12-28 14:13:21 -08002142 for (ClientDeathRecipient app : mBleApps.values()) {
Marie Janssena95924d2017-01-18 09:37:52 -08002143 writer.println(" " + app.getPackageName());
Marie Janssen59804562016-12-28 14:13:21 -08002144 }
2145
Marie Janssena95924d2017-01-18 09:37:52 -08002146 writer.println("");
Marie Janssen59804562016-12-28 14:13:21 -08002147 writer.flush();
Marie Janssenf5ec5382017-01-03 11:37:38 -08002148 if (args.length == 0) {
Marie Janssena95924d2017-01-18 09:37:52 -08002149 // Add arg to produce output
2150 args = new String[1];
2151 args[0] = "--print";
Marie Janssenf5ec5382017-01-03 11:37:38 -08002152 }
Marie Janssen59804562016-12-28 14:13:21 -08002153 }
2154
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002155 if (mBluetoothBinder == null) {
2156 errorMsg = "Bluetooth Service not connected";
2157 } else {
2158 try {
2159 mBluetoothBinder.dump(fd, args);
2160 } catch (RemoteException re) {
Marie Janssen59804562016-12-28 14:13:21 -08002161 errorMsg = "RemoteException while dumping Bluetooth Service";
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002162 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002163 }
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002164 if (errorMsg != null) {
2165 // Silently return if we are extracting metrics in Protobuf format
Marie Janssen59804562016-12-28 14:13:21 -08002166 if (protoOut) return;
Pavlin Radoslavov6e8faff2016-02-23 11:54:37 -08002167 writer.println(errorMsg);
2168 }
Mike Lockwood726d4de2014-10-28 14:06:28 -07002169 }
fredc0f420372012-04-12 00:02:00 -07002170}