Merge "[Settings] Avoid NPE if BT device is changed by framework." into udc-dev
This commit is contained in:
@@ -57,7 +57,9 @@ import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -92,6 +94,7 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
@VisibleForTesting
|
||||
final Map<String, Bitmap> mIconCache;
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private Set<BluetoothDevice> mBluetoothDevices;
|
||||
@VisibleForTesting
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
@VisibleForTesting
|
||||
@@ -141,23 +144,13 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
if (!isAvailable()) {
|
||||
return;
|
||||
}
|
||||
mIsRegisterCallback = true;
|
||||
mCachedDevice.registerCallback(this);
|
||||
mBluetoothAdapter.addOnMetadataChangedListener(mCachedDevice.getDevice(),
|
||||
mContext.getMainExecutor(), mMetadataListener);
|
||||
|
||||
registerBluetoothDevice();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (!mIsRegisterCallback) {
|
||||
return;
|
||||
}
|
||||
mCachedDevice.unregisterCallback(this);
|
||||
mBluetoothAdapter.removeOnMetadataChangedListener(mCachedDevice.getDevice(),
|
||||
mMetadataListener);
|
||||
mIsRegisterCallback = false;
|
||||
unRegisterBluetoothDevice();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,6 +168,40 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
mCachedDevice = cachedBluetoothDevice;
|
||||
}
|
||||
|
||||
private void registerBluetoothDevice() {
|
||||
if (mBluetoothDevices == null) {
|
||||
mBluetoothDevices = new HashSet<>();
|
||||
}
|
||||
mBluetoothDevices.clear();
|
||||
if (mCachedDevice.getDevice() != null) {
|
||||
mBluetoothDevices.add(mCachedDevice.getDevice());
|
||||
}
|
||||
mCachedDevice.getMemberDevice().forEach(cbd -> {
|
||||
if (cbd != null) {
|
||||
mBluetoothDevices.add(cbd.getDevice());
|
||||
}
|
||||
});
|
||||
if (mBluetoothDevices.isEmpty()) {
|
||||
Log.d(TAG, "No BT devcie to register.");
|
||||
return;
|
||||
}
|
||||
mCachedDevice.registerCallback(this);
|
||||
mBluetoothDevices.forEach(bd ->
|
||||
mBluetoothAdapter.addOnMetadataChangedListener(bd,
|
||||
mContext.getMainExecutor(), mMetadataListener));
|
||||
}
|
||||
|
||||
private void unRegisterBluetoothDevice() {
|
||||
if (mBluetoothDevices == null || mBluetoothDevices.isEmpty()) {
|
||||
Log.d(TAG, "No BT devcie to unregister.");
|
||||
return;
|
||||
}
|
||||
mCachedDevice.unregisterCallback(this);
|
||||
mBluetoothDevices.forEach(bd -> mBluetoothAdapter.removeOnMetadataChangedListener(bd,
|
||||
mMetadataListener));
|
||||
mBluetoothDevices.clear();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void refresh() {
|
||||
if (mLayoutPreference != null && mCachedDevice != null) {
|
||||
|
@@ -56,6 +56,9 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class})
|
||||
public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
@@ -380,40 +383,68 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
Set<CachedBluetoothDevice> cacheBluetoothDevices = new HashSet<>();
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(cacheBluetoothDevices);
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice).registerCallback(mController);
|
||||
verify(mBluetoothAdapter).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_isRegisterCallback_unregisterCallback() {
|
||||
mController.mIsRegisterCallback = true;
|
||||
|
||||
mController.onStop();
|
||||
|
||||
verify(mBluetoothAdapter).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_notAvailable_registerCallback() {
|
||||
public void onStart_notAvailable_notNeedToRegisterCallback() {
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("false".getBytes());
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice, never()).registerCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_notRegisterCallback_unregisterCallback() {
|
||||
mController.mIsRegisterCallback = false;
|
||||
public void onStart_isAvailableButNoBluetoothDevice_notNeedToRegisterCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
when(mCachedDevice.getDevice()).thenReturn(null);
|
||||
Set<CachedBluetoothDevice> cacheBluetoothDevices = new HashSet<>();
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(cacheBluetoothDevices);
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice, never()).registerCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_availableAndHasBluetoothDevice_unregisterCallback() {
|
||||
onStart_isAvailable_registerCallback();
|
||||
|
||||
mController.onStop();
|
||||
|
||||
verify(mCachedDevice).unregisterCallback(mController);
|
||||
verify(mBluetoothAdapter).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_noBluetoothDevice_noNeedToUnregisterCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
when(mCachedDevice.getDevice()).thenReturn(null);
|
||||
|
||||
mController.onStart();
|
||||
mController.onStop();
|
||||
|
||||
verify(mCachedDevice, never()).unregisterCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
Reference in New Issue
Block a user