[Bluetooth] Convert BluetoothController logs to log buffer so we'll
always have them.
We're mainly interested in the activeDeviceChanged log for b/243755182
but it'll be good to have all the logs.
Bug: 243755182
Fixes: 234774643
Test: dumped log buffer from device
Test: BluetoothControllerImplTest
Change-Id: Id1b12dbf802cae07120f1d6cc2c0b2e3967a1c75
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
index 3152e65..cbdac61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
@@ -16,6 +16,20 @@
package com.android.settingslib.bluetooth;
+import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED;
+import static android.bluetooth.BluetoothAdapter.STATE_CONNECTING;
+import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTED;
+import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTING;
+import static android.bluetooth.BluetoothAdapter.STATE_OFF;
+import static android.bluetooth.BluetoothAdapter.STATE_ON;
+import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
+import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* BluetoothCallback provides a callback interface for the settings
@@ -33,7 +47,7 @@
* {@link android.bluetooth.BluetoothAdapter#STATE_ON},
* {@link android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}.
*/
- default void onBluetoothStateChanged(int bluetoothState) {}
+ default void onBluetoothStateChanged(@AdapterState int bluetoothState) {}
/**
* It will be called when the local Bluetooth adapter has started
@@ -89,7 +103,9 @@
* {@link android.bluetooth.BluetoothAdapter#STATE_CONNECTED},
* {@link android.bluetooth.BluetoothAdapter#STATE_DISCONNECTING}.
*/
- default void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {}
+ default void onConnectionStateChanged(
+ @Nullable CachedBluetoothDevice cachedDevice,
+ @ConnectionState int state) {}
/**
* It will be called when device been set as active for {@code bluetoothProfile}
@@ -124,8 +140,10 @@
* {@link android.bluetooth.BluetoothProfile#STATE_DISCONNECTING}.
* @param bluetoothProfile the BluetoothProfile id.
*/
- default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
- int state, int bluetoothProfile) {
+ default void onProfileConnectionStateChanged(
+ CachedBluetoothDevice cachedDevice,
+ @ConnectionState int state,
+ int bluetoothProfile) {
}
/**
@@ -140,4 +158,22 @@
*/
default void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "STATE_" }, value = {
+ STATE_DISCONNECTED,
+ STATE_CONNECTING,
+ STATE_CONNECTED,
+ STATE_DISCONNECTING,
+ })
+ @interface ConnectionState {}
+
+ @IntDef(prefix = { "STATE_" }, value = {
+ STATE_OFF,
+ STATE_TURNING_ON,
+ STATE_ON,
+ STATE_TURNING_OFF,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface AdapterState {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt
new file mode 100644
index 0000000..b5da7b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BluetoothLogger.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.BluetoothLog
+import javax.inject.Inject
+
+/** Helper class for logging bluetooth events. */
+@SysUISingleton
+class BluetoothLogger @Inject constructor(@BluetoothLog private val logBuffer: LogBuffer) {
+ fun logActiveDeviceChanged(address: String, profileId: Int) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = address
+ int1 = profileId
+ },
+ { "ActiveDeviceChanged. address=$str1 profileId=$int1" }
+ )
+
+ fun logDeviceConnectionStateChanged(address: String?, state: String) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = address
+ str2 = state
+ },
+ { "DeviceConnectionStateChanged. address=$str1 state=$str2" }
+ )
+
+ fun logAclConnectionStateChanged(address: String, state: String) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = address
+ str2 = state
+ },
+ { "AclConnectionStateChanged. address=$str1 state=$str2" }
+ )
+
+ fun logProfileConnectionStateChanged(address: String, state: String, profileId: Int) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = address
+ str2 = state
+ int1 = profileId
+ },
+ { "ProfileConnectionStateChanged. address=$str1 state=$str2 profileId=$int1" }
+ )
+
+ fun logStateChange(state: String) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { str1 = state },
+ { "BluetoothStateChanged. state=$str1" }
+ )
+
+ fun logBondStateChange(address: String, state: Int) =
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = address
+ int1 = state
+ },
+ { "DeviceBondStateChanged. address=$str1 state=$int1" }
+ )
+
+ fun logDeviceAdded(address: String) =
+ logBuffer.log(TAG, LogLevel.DEBUG, { str1 = address }, { "DeviceAdded. address=$str1" })
+
+ fun logDeviceDeleted(address: String) =
+ logBuffer.log(TAG, LogLevel.DEBUG, { str1 = address }, { "DeviceDeleted. address=$str1" })
+
+ fun logDeviceAttributesChanged() =
+ logBuffer.log(TAG, LogLevel.DEBUG, {}, { "DeviceAttributesChanged." })
+}
+
+private const val TAG = "BluetoothLog"
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index a3dc779..659f286 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -601,7 +601,7 @@
private final class BluetoothCallbackHandler implements BluetoothCallback {
@Override
- public void onBluetoothStateChanged(int bluetoothState) {
+ public void onBluetoothStateChanged(@BluetoothCallback.AdapterState int bluetoothState) {
mHandler.obtainMessage(MSG_ON_BLUETOOTH_STATE_CHANGED,
bluetoothState, 0).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt
new file mode 100644
index 0000000..4887b6a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BluetoothLog.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for bluetooth. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class BluetoothLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
index 323ee21..b551125 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardUpdateMonitorLog.kt
@@ -1,4 +1,9 @@
package com.android.systemui.log.dagger
+import javax.inject.Qualifier
+
/** A [com.android.systemui.log.LogBuffer] for KeyguardUpdateMonitor. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
annotation class KeyguardUpdateMonitorLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index c2a8764..eeba6b3 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -305,4 +305,14 @@
public static LogBuffer provideKeyguardUpdateMonitorLogBuffer(LogBufferFactory factory) {
return factory.create("KeyguardUpdateMonitorLog", 200);
}
+
+ /**
+ * Provides a {@link LogBuffer} for bluetooth-related logs.
+ */
+ @Provides
+ @SysUISingleton
+ @BluetoothLog
+ public static LogBuffer providerBluetoothLogBuffer(LogBufferFactory factory) {
+ return factory.create("BluetoothLog", 50);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index e7fa6d2..c7ea3c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -27,7 +27,6 @@
import android.os.Message;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.Log;
import androidx.annotation.NonNull;
@@ -37,6 +36,7 @@
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.systemui.bluetooth.BluetoothLogger;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -57,9 +57,9 @@
public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
CachedBluetoothDevice.Callback, LocalBluetoothProfileManager.ServiceListener {
private static final String TAG = "BluetoothController";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final DumpManager mDumpManager;
+ private final BluetoothLogger mLogger;
private final LocalBluetoothManager mLocalBluetoothManager;
private final UserManager mUserManager;
private final int mCurrentUser;
@@ -70,6 +70,7 @@
private final List<CachedBluetoothDevice> mConnectedDevices = new ArrayList<>();
private boolean mEnabled;
+ @ConnectionState
private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
private boolean mAudioProfileOnly;
private boolean mIsActive;
@@ -83,10 +84,12 @@
public BluetoothControllerImpl(
Context context,
DumpManager dumpManager,
+ BluetoothLogger logger,
@Background Looper bgLooper,
@Main Looper mainLooper,
@Nullable LocalBluetoothManager localBluetoothManager) {
mDumpManager = dumpManager;
+ mLogger = logger;
mLocalBluetoothManager = localBluetoothManager;
mBgHandler = new Handler(bgLooper);
mHandler = new H(mainLooper);
@@ -116,7 +119,7 @@
return;
}
pw.print(" mEnabled="); pw.println(mEnabled);
- pw.print(" mConnectionState="); pw.println(stateToString(mConnectionState));
+ pw.print(" mConnectionState="); pw.println(connectionStateToString(mConnectionState));
pw.print(" mAudioProfileOnly="); pw.println(mAudioProfileOnly);
pw.print(" mIsActive="); pw.println(mIsActive);
pw.print(" mConnectedDevices="); pw.println(getConnectedDevices());
@@ -127,7 +130,7 @@
}
}
- private static String stateToString(int state) {
+ private static String connectionStateToString(@ConnectionState int state) {
switch (state) {
case BluetoothAdapter.STATE_CONNECTED:
return "CONNECTED";
@@ -320,8 +323,8 @@
}
@Override
- public void onBluetoothStateChanged(int bluetoothState) {
- if (DEBUG) Log.d(TAG, "BluetoothStateChanged=" + stateToString(bluetoothState));
+ public void onBluetoothStateChanged(@AdapterState int bluetoothState) {
+ mLogger.logStateChange(BluetoothAdapter.nameForState(bluetoothState));
mEnabled = bluetoothState == BluetoothAdapter.STATE_ON
|| bluetoothState == BluetoothAdapter.STATE_TURNING_ON;
mState = bluetoothState;
@@ -331,7 +334,7 @@
@Override
public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
- if (DEBUG) Log.d(TAG, "DeviceAdded=" + cachedDevice.getAddress());
+ mLogger.logDeviceAdded(cachedDevice.getAddress());
cachedDevice.registerCallback(this);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
@@ -339,7 +342,7 @@
@Override
public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
- if (DEBUG) Log.d(TAG, "DeviceDeleted=" + cachedDevice.getAddress());
+ mLogger.logDeviceDeleted(cachedDevice.getAddress());
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
@@ -347,7 +350,7 @@
@Override
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
- if (DEBUG) Log.d(TAG, "DeviceBondStateChanged=" + cachedDevice.getAddress());
+ mLogger.logBondStateChange(cachedDevice.getAddress(), bondState);
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
@@ -355,29 +358,29 @@
@Override
public void onDeviceAttributesChanged() {
- if (DEBUG) Log.d(TAG, "DeviceAttributesChanged");
+ mLogger.logDeviceAttributesChanged();
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
}
@Override
- public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
- if (DEBUG) {
- Log.d(TAG, "ConnectionStateChanged=" + cachedDevice.getAddress() + " "
- + stateToString(state));
- }
+ public void onConnectionStateChanged(
+ @Nullable CachedBluetoothDevice cachedDevice,
+ @ConnectionState int state) {
+ String address = cachedDevice == null ? null : cachedDevice.getAddress();
+ mLogger.logDeviceConnectionStateChanged(address, connectionStateToString(state));
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
- public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
- int state, int bluetoothProfile) {
- if (DEBUG) {
- Log.d(TAG, "ProfileConnectionStateChanged=" + cachedDevice.getAddress() + " "
- + stateToString(state) + " profileId=" + bluetoothProfile);
- }
+ public void onProfileConnectionStateChanged(
+ CachedBluetoothDevice cachedDevice,
+ @ConnectionState int state,
+ int bluetoothProfile) {
+ mLogger.logProfileConnectionStateChanged(
+ cachedDevice.getAddress(), connectionStateToString(state), bluetoothProfile);
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
@@ -385,20 +388,15 @@
@Override
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
- if (DEBUG) {
- Log.d(TAG, "ActiveDeviceChanged=" + activeDevice.getAddress()
- + " profileId=" + bluetoothProfile);
- }
+ mLogger.logActiveDeviceChanged(activeDevice.getAddress(), bluetoothProfile);
updateActive();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
- if (DEBUG) {
- Log.d(TAG, "ACLConnectionStateChanged=" + cachedDevice.getAddress() + " "
- + stateToString(state));
- }
+ mLogger.logAclConnectionStateChanged(
+ cachedDevice.getAddress(), connectionStateToString(state));
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 3dd36d1..cf5e878 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -41,6 +41,7 @@
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.bluetooth.BluetoothLogger;
import com.android.systemui.dump.DumpManager;
import org.junit.Before;
@@ -81,6 +82,7 @@
mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
mMockDumpManager,
+ mock(BluetoothLogger.class),
mTestableLooper.getLooper(),
mTestableLooper.getLooper(),
mMockBluetoothManager);