From ffcf88f36ec8412bc274a51cad3bf03c11c614fb Mon Sep 17 00:00:00 2001 From: Marie Janssen Date: Tue, 13 Dec 2016 10:51:02 -0800 Subject: [PATCH 1/2] Bluetooth: log message improvements Some log improvements: - Reduce logspam - Use names for states in logs instead of numbers - Be more consistent with messages Also remove some commented out dead code. Test: run on phone, observe more useful logs Change-Id: I32163278e148be144c03d4e8aaf0eb761226c94c --- .../android/bluetooth/BluetoothAdapter.java | 97 +++---- .../server/BluetoothManagerService.java | 246 +++++++++--------- 2 files changed, 153 insertions(+), 190 deletions(-) diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 542b06b136054..5ced03b2c2dce 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -200,6 +200,23 @@ public final class BluetoothAdapter { */ public static final int STATE_BLE_TURNING_OFF = 16; + /** + * Human-readable string helper for AdapterState + * @hide + */ + public static String nameForState(@AdapterState int state) { + switch(state) { + case STATE_OFF: return "OFF"; + case STATE_TURNING_ON: return "TURNING_ON"; + case STATE_ON: return "ON"; + case STATE_TURNING_OFF: return "TURNING_OFF"; + case STATE_BLE_TURNING_ON: return "BLE_TURNING_ON"; + case STATE_BLE_ON: return "BLE_ON"; + case STATE_BLE_TURNING_OFF: return "BLE_TURNING_OFF"; + default: return "?!?!? (" + state + ")"; + } + } + /** * Activity Action: Show a system activity that requests discoverable mode. * This activity will also request the user to turn on Bluetooth if it @@ -662,15 +679,8 @@ public final class BluetoothAdapter { @SystemApi public boolean isLeEnabled() { final int state = getLeState(); - if (state == BluetoothAdapter.STATE_ON) { - if (DBG) Log.d (TAG, "STATE_ON"); - } else if (state == BluetoothAdapter.STATE_BLE_ON) { - if (DBG) Log.d (TAG, "STATE_BLE_ON"); - } else { - if (DBG) Log.d (TAG, "STATE_OFF"); - return false; - } - return true; + if (DBG) Log.d(TAG, "isLeEnabled(): " + BluetoothAdapter.nameForState(state)); + return (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON); } /** @@ -835,10 +845,10 @@ public final class BluetoothAdapter { if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) { - if (VDBG) Log.d(TAG, "Consider internal state as OFF"); + if (VDBG) Log.d(TAG, "Consider " + BluetoothAdapter.nameForState(state) + " state as OFF"); state = BluetoothAdapter.STATE_OFF; } - if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state); + if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + BluetoothAdapter.nameForState(state)); return state; } @@ -875,12 +885,12 @@ public final class BluetoothAdapter { mServiceLock.readLock().unlock(); } - if (VDBG) Log.d(TAG,"getLeState() returning " + state); + if (VDBG) Log.d(TAG,"getLeState() returning " + BluetoothAdapter.nameForState(state)); return state; } boolean getLeAccess() { - if(getLeState() == STATE_ON) + if (getLeState() == STATE_ON) return true; else if (getLeState() == STATE_BLE_ON) @@ -918,8 +928,8 @@ public final class BluetoothAdapter { */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean enable() { - if (isEnabled() == true) { - if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); + if (isEnabled()) { + if (DBG) Log.d(TAG, "enable(): BT already enabled!"); return true; } try { @@ -1540,8 +1550,9 @@ public final class BluetoothAdapter { } } } - } catch (RemoteException e) {Log.e(TAG, "getSupportedProfiles:", e);} - + } catch (RemoteException e) { + Log.e(TAG, "getSupportedProfiles:", e); + } return supportedProfiles; } @@ -1892,34 +1903,6 @@ public final class BluetoothAdapter { * @hide */ public Pair readOutOfBandData() { - if (getState() != STATE_ON) return null; - //TODO(BT - /* - try { - byte[] hash; - byte[] randomizer; - - byte[] ret = null; - mServiceLock.readLock().lock(); - if (mService != null) mService.readOutOfBandData(); - - if (ret == null || ret.length != 32) return null; - - hash = Arrays.copyOfRange(ret, 0, 16); - randomizer = Arrays.copyOfRange(ret, 16, 32); - - if (DBG) { - Log.d(TAG, "readOutOfBandData:" + Arrays.toString(hash) + - ":" + Arrays.toString(randomizer)); - } - return new Pair(hash, randomizer); - - } catch (RemoteException e) { - Log.e(TAG, "", e); - } finally { - mServiceLock.readLock().unlock(); - } - */ return null; } @@ -2066,7 +2049,7 @@ public final class BluetoothAdapter { if (cb != null) { cb.onBluetoothServiceUp(bluetoothService); } else { - Log.d(TAG, "onBluetoothServiceUp: cb is null!!!"); + Log.d(TAG, "onBluetoothServiceUp: cb is null!"); } } catch (Exception e) { Log.e(TAG,"",e); @@ -2094,7 +2077,7 @@ public final class BluetoothAdapter { if (cb != null) { cb.onBluetoothServiceDown(); } else { - Log.d(TAG, "onBluetoothServiceDown: cb is null!!!"); + Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG,"",e); @@ -2104,7 +2087,7 @@ public final class BluetoothAdapter { } public void onBrEdrDown() { - if (DBG) Log.i(TAG, "onBrEdrDown:"); + if (VDBG) Log.i(TAG, "onBrEdrDown: " + mService); } }; @@ -2115,7 +2098,7 @@ public final class BluetoothAdapter { */ public boolean enableNoAutoConnect() { if (isEnabled() == true){ - if (DBG) Log.d(TAG, "enableNoAutoConnect(): BT is already enabled..!"); + if (DBG) Log.d(TAG, "enableNoAutoConnect(): BT already enabled!"); return true; } try { @@ -2155,22 +2138,6 @@ public final class BluetoothAdapter { */ public boolean changeApplicationBluetoothState(boolean on, BluetoothStateChangeCallback callback) { - if (callback == null) return false; - - //TODO(BT) - /* - try { - mServiceLock.readLock().lock(); - if (mService != null) { - return mService.changeApplicationBluetoothState(on, new - StateChangeCallbackWrapper(callback), new Binder()); - } - } catch (RemoteException e) { - Log.e(TAG, "changeBluetoothState", e); - } finally { - mServiceLock.readLock().unlock(); - } - */ return false; } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index dbb8e0f44baf9..b2e38d86757d9 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -101,6 +101,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final int MESSAGE_USER_UNLOCKED = 301; private static final int MESSAGE_ADD_PROXY_DELAYED = 400; private static final int MESSAGE_BIND_PROFILE_SERVICE = 401; + private static final int MAX_SAVE_RETRIES = 3; private static final int MAX_ERROR_RESTART_RETRIES = 6; @@ -207,7 +208,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } finally { mBluetoothLock.readLock().unlock(); } - Slog.d(TAG, "Airplane Mode change - current state: " + st); + Slog.d(TAG, "State " + BluetoothAdapter.nameForState(st)); if (isAirplaneModeOn()) { // Clear registered LE apps to force shut-off @@ -405,6 +406,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); + if (callback == null) { + Slog.w(TAG, "registerStateChangeCallback: Callback is null!"); + return; + } Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK); msg.obj = callback; mHandler.sendMessage(msg); @@ -413,6 +418,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); + if (callback == null) { + Slog.w(TAG, "unregisterStateChangeCallback: Callback is null!"); + return; + } Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK); msg.obj = callback; mHandler.sendMessage(msg); @@ -439,7 +448,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { public int getState() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) { - Slog.w(TAG, "getState(): not allowed for non-active and non system user"); + Slog.w(TAG, "getState(): report OFF for non-active and non system user"); return BluetoothAdapter.STATE_OFF; } @@ -677,7 +686,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (DBG) { Slog.d(TAG,"enable(): mBluetooth =" + mBluetooth + - " mBinding = " + mBinding + " mState = " + mState); + " mBinding = " + mBinding + " mState = " + + BluetoothAdapter.nameForState(mState)); } synchronized(mReceiver) { @@ -756,7 +766,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { public void unbindAndFinish() { if (DBG) { Slog.d(TAG,"unbindAndFinish(): " + mBluetooth + - " mBinding = " + mBinding); + " mBinding = " + mBinding + " mUnbinding = " + mUnbinding); } try { @@ -772,16 +782,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } catch (RemoteException re) { Slog.e(TAG, "Unable to unregister BluetoothCallback",re); } - - if (DBG) Slog.d(TAG, "Sending unbind request."); mBluetoothBinder = null; mBluetooth = null; - //Unbind mContext.unbindService(mConnection); mUnbinding = false; mBinding = false; } else { - mUnbinding=false; + mUnbinding = false; } mBluetoothGatt = null; } finally { @@ -1051,7 +1058,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { * Inform BluetoothAdapter instances that Adapter service is up */ private void sendBluetoothServiceUpCallback() { - if (DBG) Slog.d(TAG,"Calling onBluetoothServiceUp callbacks"); try { int n = mCallbacks.beginBroadcast(); Slog.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers."); @@ -1070,7 +1076,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { * Inform BluetoothAdapter instances that Adapter service is down */ private void sendBluetoothServiceDownCallback() { - if (DBG) Slog.d(TAG,"Calling onBluetoothServiceDown callbacks"); try { int n = mCallbacks.beginBroadcast(); Slog.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers."); @@ -1142,34 +1147,33 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private class BluetoothServiceConnection implements ServiceConnection { - public void onServiceConnected(ComponentName className, IBinder service) { - if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + className.getClassName()); + public void onServiceConnected(ComponentName componentName, IBinder service) { + String name = componentName.getClassName(); + if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); - // TBD if (className.getClassName().equals(IBluetooth.class.getName())) { - if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { + if (name.equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; - // } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) { - } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { + } else if (name.equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { - Slog.e(TAG, "Unknown service connected: " + className.getClassName()); + Slog.e(TAG, "Unknown service connected: " + name); return; } msg.obj = service; mHandler.sendMessage(msg); } - public void onServiceDisconnected(ComponentName className) { - // Called if we unexpected disconnected. - if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + - className.getClassName()); + public void onServiceDisconnected(ComponentName componentName) { + // Called if we unexpectedly disconnect. + String name = componentName.getClassName(); + if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + name); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); - if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { + if (name.equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; - } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { + } else if (name.equals("com.android.bluetooth.gatt.GattService")) { msg.arg1 = SERVICE_IBLUETOOTHGATT; } else { - Slog.e(TAG, "Unknown service disconnected: " + className.getClassName()); + Slog.e(TAG, "Unknown service disconnected: " + name); return; } mHandler.sendMessage(msg); @@ -1187,7 +1191,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { @Override public void handleMessage(Message msg) { - if (DBG) Slog.d (TAG, "Message: " + msg.what); switch (msg.what) { case MESSAGE_GET_NAME_AND_ADDRESS: if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS"); @@ -1225,7 +1228,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { case MESSAGE_ENABLE: if (DBG) { - Slog.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth); + Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; @@ -1275,6 +1278,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { break; case MESSAGE_DISABLE: + if (DBG) Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth); mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); if (mEnable && mBluetooth != null) { waitForOnOff(true, false); @@ -1290,31 +1294,25 @@ class BluetoothManagerService extends IBluetoothManager.Stub { case MESSAGE_REGISTER_ADAPTER: { IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj; - boolean added = mCallbacks.register(callback); - Slog.d(TAG,"Added callback: " + (callback == null? "null": callback) +":" +added ); - } + mCallbacks.register(callback); break; + } case MESSAGE_UNREGISTER_ADAPTER: { IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj; - boolean removed = mCallbacks.unregister(callback); - Slog.d(TAG,"Removed callback: " + (callback == null? "null": callback) +":" + removed); + mCallbacks.unregister(callback); break; } case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: { IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj; - if (callback != null) { - mStateChangeCallbacks.register(callback); - } + mStateChangeCallbacks.register(callback); break; } case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: { IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj; - if (callback != null) { - mStateChangeCallbacks.unregister(callback); - } + mStateChangeCallbacks.unregister(callback); break; } case MESSAGE_ADD_PROXY_DELAYED: @@ -1387,13 +1385,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub { //Do enable request try { if (mQuietEnable == false) { - if(!mBluetooth.enable()) { + if (!mBluetooth.enable()) { Slog.e(TAG,"IBluetooth.enable() returned false"); } - } - else - { - if(!mBluetooth.enableNoAutoConnect()) { + } else { + if (!mBluetooth.enableNoAutoConnect()) { Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); } } @@ -1411,19 +1407,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } break; } - case MESSAGE_TIMEOUT_BIND: { - Slog.e(TAG, "MESSAGE_TIMEOUT_BIND"); - mBluetoothLock.writeLock().lock(); - mBinding = false; - mBluetoothLock.writeLock().unlock(); - - break; - } case MESSAGE_BLUETOOTH_STATE_CHANGE: { int prevState = msg.arg1; int newState = msg.arg2; - if (DBG) Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = " + prevState + ", newState =" + newState); + if (DBG) { + Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState(prevState) + " > " + + BluetoothAdapter.nameForState(newState)); + } mState = newState; bluetoothStateChangeHandler(prevState, newState); // handle error state transition case from TURNING_ON to OFF @@ -1463,7 +1454,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: { - Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1); + Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED(" + msg.arg1 + ")"); try { mBluetoothLock.writeLock().lock(); if (msg.arg1 == SERVICE_IBLUETOOTH) { @@ -1474,7 +1465,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mBluetoothGatt = null; break; } else { - Slog.e(TAG, "Bad msg.arg1: " + msg.arg1); + Slog.e(TAG, "Unknown argument for service disconnect!"); break; } } finally { @@ -1511,8 +1502,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } case MESSAGE_RESTART_BLUETOOTH_SERVICE: { - Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE:" - +" Restart IBluetooth service"); + Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE"); /* Enable without persisting the setting as it doesnt change when IBluetooth service restarts */ @@ -1520,7 +1510,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { handleEnable(mQuietEnable); break; } - + case MESSAGE_TIMEOUT_BIND: { + Slog.e(TAG, "MESSAGE_TIMEOUT_BIND"); + mBluetoothLock.writeLock().lock(); + mBinding = false; + mBluetoothLock.writeLock().unlock(); + break; + } case MESSAGE_TIMEOUT_UNBIND: { Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND"); @@ -1606,11 +1602,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } else if (mBinding || mBluetooth != null) { Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED); userMsg.arg2 = 1 + msg.arg2; - // if user is switched when service is being binding - // delay sending MESSAGE_USER_SWITCHED + // if user is switched when service is binding retry after a delay mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS); if (DBG) { - Slog.d(TAG, "delay MESSAGE_USER_SWITCHED " + userMsg.arg2); + Slog.d(TAG, "Retry MESSAGE_USER_SWITCHED " + userMsg.arg2); } } break; @@ -1711,7 +1706,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { parentUser == foregroundUser || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid; - if (DBG) { + if (DBG && !valid) { Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser=" + callingUser + " parentUser=" + parentUser @@ -1724,7 +1719,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private void sendBleStateChanged(int prevState, int newState) { - if (DBG) Slog.d(TAG,"BLE State Change Intent: " + prevState + " -> " + newState); + if (DBG) Slog.d(TAG,"Sending BLE State Change: " + BluetoothAdapter.nameForState(prevState) + + " > " + BluetoothAdapter.nameForState(newState)); // Send broadcast message to everyone else Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); @@ -1735,76 +1731,76 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private void bluetoothStateChangeHandler(int prevState, int newState) { boolean isStandardBroadcast = true; - if (DBG) Slog.d(TAG, "bluetoothStateChangeHandler: " + prevState + " -> " + newState); - if (prevState != newState) { - //Notify all proxy objects first of adapter state change - if (newState == BluetoothAdapter.STATE_BLE_ON || - newState == BluetoothAdapter.STATE_OFF) { - boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF - && newState == BluetoothAdapter.STATE_BLE_ON); + if (prevState == newState) { // No change. Nothing to do. + return; + } + // Notify all proxy objects first of adapter state change + if (newState == BluetoothAdapter.STATE_BLE_ON || + newState == BluetoothAdapter.STATE_OFF) { + boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF + && newState == BluetoothAdapter.STATE_BLE_ON); - if (newState == BluetoothAdapter.STATE_OFF) { - // If Bluetooth is off, send service down event to proxy objects, and unbind - if (DBG) Slog.d(TAG, "Bluetooth is complete turn off"); - sendBluetoothServiceDownCallback(); - unbindAndFinish(); - sendBleStateChanged(prevState, newState); - // Don't broadcast as it has already been broadcast before - isStandardBroadcast = false; - - } else if (!intermediate_off) { - // connect to GattService - if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode"); - if (mBluetoothGatt != null) { - if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp"); - onBluetoothGattServiceUp(); - } else { - if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service"); - if (mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_BLUETOOTH_LE)) { - Intent i = new Intent(IBluetoothGatt.class.getName()); - doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT); - } - } - sendBleStateChanged(prevState, newState); - //Don't broadcase this as std intent - isStandardBroadcast = false; - - } else if (intermediate_off){ - if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode"); - // For LE only mode, broadcast as is - sendBleStateChanged(prevState, newState); - sendBluetoothStateCallback(false); // BT is OFF for general users - // Broadcast as STATE_OFF - newState = BluetoothAdapter.STATE_OFF; - sendBrEdrDownCallback(); - } - } else if (newState == BluetoothAdapter.STATE_ON) { - boolean isUp = (newState==BluetoothAdapter.STATE_ON); - sendBluetoothStateCallback(isUp); - sendBleStateChanged(prevState, newState); - - } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON || - newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) { + if (newState == BluetoothAdapter.STATE_OFF) { + // If Bluetooth is off, send service down event to proxy objects, and unbind + if (DBG) Slog.d(TAG, "Bluetooth is complete send Service Down"); + sendBluetoothServiceDownCallback(); + unbindAndFinish(); sendBleStateChanged(prevState, newState); + // Don't broadcast as it has already been broadcast before isStandardBroadcast = false; - } else if (newState == BluetoothAdapter.STATE_TURNING_ON || - newState == BluetoothAdapter.STATE_TURNING_OFF) { - sendBleStateChanged(prevState, newState); - } - - if (isStandardBroadcast) { - if (prevState == BluetoothAdapter.STATE_BLE_ON) { - // Show prevState of BLE_ON as OFF to standard users - prevState = BluetoothAdapter.STATE_OFF; + } else if (!intermediate_off) { + // connect to GattService + if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode"); + if (mBluetoothGatt != null) { + if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp"); + onBluetoothGattServiceUp(); + } else { + if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service"); + if (mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_BLUETOOTH_LE)) { + Intent i = new Intent(IBluetoothGatt.class.getName()); + doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT); + } } - Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); - intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); - intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM); + sendBleStateChanged(prevState, newState); + //Don't broadcase this as std intent + isStandardBroadcast = false; + + } else if (intermediate_off) { + if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode"); + // For LE only mode, broadcast as is + sendBleStateChanged(prevState, newState); + sendBluetoothStateCallback(false); // BT is OFF for general users + // Broadcast as STATE_OFF + newState = BluetoothAdapter.STATE_OFF; + sendBrEdrDownCallback(); } + } else if (newState == BluetoothAdapter.STATE_ON) { + boolean isUp = (newState == BluetoothAdapter.STATE_ON); + sendBluetoothStateCallback(isUp); + sendBleStateChanged(prevState, newState); + + } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON || + newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) { + sendBleStateChanged(prevState, newState); + isStandardBroadcast = false; + + } else if (newState == BluetoothAdapter.STATE_TURNING_ON || + newState == BluetoothAdapter.STATE_TURNING_OFF) { + sendBleStateChanged(prevState, newState); + } + + if (isStandardBroadcast) { + if (prevState == BluetoothAdapter.STATE_BLE_ON) { + // Show prevState of BLE_ON as OFF to standard users + prevState = BluetoothAdapter.STATE_OFF; + } + Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); + intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); + intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM); } } From fa63068deb3b42b1907c0c2214204e2f4e31bd0c Mon Sep 17 00:00:00 2001 From: Marie Janssen Date: Thu, 15 Dec 2016 13:51:30 -0800 Subject: [PATCH 2/2] Bluetooth: fix issues re-enabling after crash When Bluetooth crashes, sometimes an LE app restarts it before ActivityManager gets a chance. In this case, the Bluetooth manager would assume the state should be LE only and did not continue to fully enabled. Luckily in this case the persisted system state is also ON. Use the persisted state as information about whether we should be fully enabled. Test: basic sanity check, forced crash of BT Bug: 33632976 Change-Id: I546d7abccb82a26fcca2eb70d6d7c76e9510404e --- .../server/BluetoothManagerService.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index b2e38d86757d9..9b212083911fc 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -317,13 +317,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { /** * Save the Bluetooth on/off state - * */ private void persistBluetoothSetting(int value) { if (DBG) Slog.d(TAG, "Persisting Bluetooth Setting: " + value); + // waive WRITE_SECURE_SETTINGS permission check + long callingIdentity = Binder.clearCallingIdentity(); Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value); + Binder.restoreCallingIdentity(callingIdentity); } /** @@ -588,20 +590,26 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } /** - * Action taken when GattService is turned off + * Action taken when GattService is turned on */ private void onBluetoothGattServiceUp() { if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up"); try { mBluetoothLock.readLock().lock(); - if (isBleAppPresent() == false && mBluetooth != null - && mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) { + if (mBluetooth == null) { + if (DBG) Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!"); + return; + } + int st = mBluetooth.getState(); + if (st != BluetoothAdapter.STATE_BLE_ON) { + if (DBG) Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " + + BluetoothAdapter.nameForState(st)); + return; + } + if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) { + // This triggers transition to STATE_ON mBluetooth.onLeServiceUp(); - - // waive WRITE_SECURE_SETTINGS permission check - long callingIdentity = Binder.clearCallingIdentity(); persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); - Binder.restoreCallingIdentity(callingIdentity); } } catch (RemoteException e) { Slog.e(TAG,"Unable to call onServiceUp", e); @@ -727,10 +735,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { synchronized(mReceiver) { if (persist) { - // waive WRITE_SECURE_SETTINGS permission check - long callingIdentity = Binder.clearCallingIdentity(); persistBluetoothSetting(BLUETOOTH_OFF); - Binder.restoreCallingIdentity(callingIdentity); } mEnableExternal = false; sendDisableMsg();