Merge "[Bluetooth] Convert BluetoothController logs to log buffer so we'll always have them." into tm-qpr-dev

This commit is contained in:
Caitlin Shkuratov
2022-09-16 14:06:14 +00:00
committed by Android (Google) Code Review
9 changed files with 251 additions and 51 deletions

View File

@@ -16,6 +16,22 @@
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 androidx.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* BluetoothCallback provides a callback interface for the settings
@@ -33,7 +49,7 @@ public interface BluetoothCallback {
* {@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
@@ -54,14 +70,14 @@ public interface BluetoothCallback {
*
* @param cachedDevice the Bluetooth device.
*/
default void onDeviceAdded(CachedBluetoothDevice cachedDevice) {}
default void onDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {}
/**
* It will be called when requiring to remove a remote device from CachedBluetoothDevice list
*
* @param cachedDevice the Bluetooth device.
*/
default void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {}
default void onDeviceDeleted(@NonNull CachedBluetoothDevice cachedDevice) {}
/**
* It will be called when bond state of a remote device is changed.
@@ -73,7 +89,8 @@ public interface BluetoothCallback {
* {@link android.bluetooth.BluetoothDevice#BOND_BONDING},
* {@link android.bluetooth.BluetoothDevice#BOND_BONDED}.
*/
default void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {}
default void onDeviceBondStateChanged(
@NonNull CachedBluetoothDevice cachedDevice, int bondState) {}
/**
* It will be called in following situations:
@@ -89,7 +106,9 @@ public interface BluetoothCallback {
* {@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}
@@ -101,7 +120,8 @@ public interface BluetoothCallback {
* @param activeDevice the active Bluetooth device.
* @param bluetoothProfile the profile of active Bluetooth device.
*/
default void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {}
default void onActiveDeviceChanged(
@Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {}
/**
* It will be called in following situations:
@@ -124,8 +144,10 @@ public interface BluetoothCallback {
* {@link android.bluetooth.BluetoothProfile#STATE_DISCONNECTING}.
* @param bluetoothProfile the BluetoothProfile id.
*/
default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
int state, int bluetoothProfile) {
default void onProfileConnectionStateChanged(
@NonNull CachedBluetoothDevice cachedDevice,
@ConnectionState int state,
int bluetoothProfile) {
}
/**
@@ -138,6 +160,24 @@ public interface BluetoothCallback {
* {@link android.bluetooth.BluetoothAdapter#STATE_DISCONNECTED},
* {@link android.bluetooth.BluetoothAdapter#STATE_CONNECTED}
*/
default void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
}
default void onAclConnectionStateChanged(
@NonNull 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 {}
}

View File

@@ -32,6 +32,7 @@ import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -193,19 +194,19 @@ public class BluetoothEventManager {
return deviceAdded;
}
void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
void dispatchDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {
for (BluetoothCallback callback : mCallbacks) {
callback.onDeviceAdded(cachedDevice);
}
}
void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
void dispatchDeviceRemoved(@NonNull CachedBluetoothDevice cachedDevice) {
for (BluetoothCallback callback : mCallbacks) {
callback.onDeviceDeleted(cachedDevice);
}
}
void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state,
void dispatchProfileConnectionStateChanged(@NonNull CachedBluetoothDevice device, int state,
int bluetoothProfile) {
for (BluetoothCallback callback : mCallbacks) {
callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
@@ -228,7 +229,8 @@ public class BluetoothEventManager {
}
@VisibleForTesting
void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice,
void dispatchActiveDeviceChanged(
@Nullable CachedBluetoothDevice activeDevice,
int bluetoothProfile) {
for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) {
boolean isActive = Objects.equals(cachedDevice, activeDevice);
@@ -239,7 +241,7 @@ public class BluetoothEventManager {
}
}
private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, int state) {
private void dispatchAclStateChanged(@NonNull CachedBluetoothDevice activeDevice, int state) {
for (BluetoothCallback callback : mCallbacks) {
callback.onAclConnectionStateChanged(activeDevice, state);
}
@@ -456,6 +458,7 @@ public class BluetoothEventManager {
Log.w(TAG, "ActiveDeviceChangedHandler: action is null");
return;
}
@Nullable
CachedBluetoothDevice activeDevice = mDeviceManager.findDevice(device);
int bluetoothProfile = 0;
if (Objects.equals(action, BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) {

View File

@@ -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"

View File

@@ -42,6 +42,8 @@ import android.util.Pair;
import android.util.Slog;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -601,13 +603,14 @@ public class KeyboardUI extends CoreStartable implements InputManager.OnTabletMo
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();
}
@Override
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
public void onDeviceBondStateChanged(
@NonNull CachedBluetoothDevice cachedDevice, int bondState) {
mHandler.obtainMessage(MSG_ON_DEVICE_BOND_STATE_CHANGED,
bondState, 0, cachedDevice).sendToTarget();
}

View File

@@ -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

View File

@@ -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

View File

@@ -316,4 +316,14 @@ public class LogModule {
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);
}
}

View File

@@ -27,7 +27,6 @@ import android.os.Looper;
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.CachedBluetoothDevice;
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 @@ import javax.inject.Inject;
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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
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 class BluetoothControllerImpl implements BluetoothController, BluetoothCa
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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
}
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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
@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;
@@ -330,24 +333,25 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
@Override
public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
if (DEBUG) Log.d(TAG, "DeviceAdded=" + cachedDevice.getAddress());
public void onDeviceAdded(@NonNull CachedBluetoothDevice cachedDevice) {
mLogger.logDeviceAdded(cachedDevice.getAddress());
cachedDevice.registerCallback(this);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
}
@Override
public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
if (DEBUG) Log.d(TAG, "DeviceDeleted=" + cachedDevice.getAddress());
public void onDeviceDeleted(@NonNull CachedBluetoothDevice cachedDevice) {
mLogger.logDeviceDeleted(cachedDevice.getAddress());
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
}
@Override
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
if (DEBUG) Log.d(TAG, "DeviceBondStateChanged=" + cachedDevice.getAddress());
public void onDeviceBondStateChanged(
@NonNull CachedBluetoothDevice cachedDevice, int bondState) {
mLogger.logBondStateChange(cachedDevice.getAddress(), bondState);
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
@@ -355,50 +359,47 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
@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) {
mLogger.logDeviceConnectionStateChanged(
getAddressOrNull(cachedDevice), 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(
@NonNull CachedBluetoothDevice cachedDevice,
@ConnectionState int state,
int bluetoothProfile) {
mLogger.logProfileConnectionStateChanged(
cachedDevice.getAddress(), connectionStateToString(state), bluetoothProfile);
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
if (DEBUG) {
Log.d(TAG, "ActiveDeviceChanged=" + activeDevice.getAddress()
+ " profileId=" + bluetoothProfile);
}
public void onActiveDeviceChanged(
@Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {
mLogger.logActiveDeviceChanged(getAddressOrNull(activeDevice), 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));
}
public void onAclConnectionStateChanged(
@NonNull CachedBluetoothDevice cachedDevice, int state) {
mLogger.logAclConnectionStateChanged(
cachedDevice.getAddress(), connectionStateToString(state));
mCachedState.remove(cachedDevice);
updateConnected();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
@@ -415,6 +416,11 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
return state;
}
@Nullable
private String getAddressOrNull(@Nullable CachedBluetoothDevice device) {
return device == null ? null : device.getAddress();
}
@Override
public void onServiceConnected() {
updateConnected();

View File

@@ -41,6 +41,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
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 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
mMockDumpManager,
mock(BluetoothLogger.class),
mTestableLooper.getLooper(),
mTestableLooper.getLooper(),
mMockBluetoothManager);
@@ -233,4 +235,11 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
assertTrue(mBluetoothControllerImpl.isBluetoothAudioActive());
assertTrue(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
}
/** Regression test for b/246876230. */
@Test
public void testOnActiveDeviceChanged_null_noCrash() {
mBluetoothControllerImpl.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
// No assert, just need no crash.
}
}