Merge "Fix null point exception on MediaDevice" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-05-13 06:03:32 +00:00
committed by Android (Google) Code Review

View File

@@ -25,6 +25,7 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.A2dpProfile;
@@ -65,6 +66,7 @@ public class LocalMediaManager implements BluetoothCallback {
} }
private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>(); private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>();
private final Object mMediaDevicesLock = new Object();
@VisibleForTesting @VisibleForTesting
final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback(); final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
@@ -145,7 +147,14 @@ public class LocalMediaManager implements BluetoothCallback {
* @param connectDevice the MediaDevice * @param connectDevice the MediaDevice
*/ */
public void connectDevice(MediaDevice connectDevice) { public void connectDevice(MediaDevice connectDevice) {
final MediaDevice device = getMediaDeviceById(mMediaDevices, connectDevice.getId()); MediaDevice device = null;
synchronized (mMediaDevicesLock) {
device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
}
if (device == null) {
Log.w(TAG, "connectDevice() connectDevice not in the list!");
return;
}
if (device instanceof BluetoothMediaDevice) { if (device instanceof BluetoothMediaDevice) {
final CachedBluetoothDevice cachedDevice = final CachedBluetoothDevice cachedDevice =
((BluetoothMediaDevice) device).getCachedDevice(); ((BluetoothMediaDevice) device).getCachedDevice();
@@ -184,15 +193,18 @@ public class LocalMediaManager implements BluetoothCallback {
* Start scan connected MediaDevice * Start scan connected MediaDevice
*/ */
public void startScan() { public void startScan() {
mMediaDevices.clear(); synchronized (mMediaDevicesLock) {
mMediaDevices.clear();
}
mInfoMediaManager.registerCallback(mMediaDeviceCallback); mInfoMediaManager.registerCallback(mMediaDeviceCallback);
mInfoMediaManager.startScan(); mInfoMediaManager.startScan();
} }
void dispatchDeviceListUpdate() { void dispatchDeviceListUpdate() {
Collections.sort(mMediaDevices, COMPARATOR); final List<MediaDevice> mediaDevices = new ArrayList<>(mMediaDevices);
Collections.sort(mediaDevices, COMPARATOR);
for (DeviceCallback callback : getCallbacks()) { for (DeviceCallback callback : getCallbacks()) {
callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices)); callback.onDeviceListUpdate(mediaDevices);
} }
} }
@@ -241,9 +253,11 @@ public class LocalMediaManager implements BluetoothCallback {
* @return MediaDevice * @return MediaDevice
*/ */
public MediaDevice getMediaDeviceById(String id) { public MediaDevice getMediaDeviceById(String id) {
for (MediaDevice mediaDevice : mMediaDevices) { synchronized (mMediaDevicesLock) {
if (TextUtils.equals(mediaDevice.getId(), id)) { for (MediaDevice mediaDevice : mMediaDevices) {
return mediaDevice; if (TextUtils.equals(mediaDevice.getId(), id)) {
return mediaDevice;
}
} }
} }
Log.i(TAG, "Unable to find device " + id); Log.i(TAG, "Unable to find device " + id);
@@ -255,6 +269,7 @@ public class LocalMediaManager implements BluetoothCallback {
* *
* @return MediaDevice * @return MediaDevice
*/ */
@Nullable
public MediaDevice getCurrentConnectedDevice() { public MediaDevice getCurrentConnectedDevice() {
return mCurrentConnectedDevice; return mCurrentConnectedDevice;
} }
@@ -367,17 +382,19 @@ public class LocalMediaManager implements BluetoothCallback {
} }
private MediaDevice updateCurrentConnectedDevice() { private MediaDevice updateCurrentConnectedDevice() {
MediaDevice phoneMediaDevice = null; synchronized (mMediaDevicesLock) {
for (MediaDevice device : mMediaDevices) { for (MediaDevice device : mMediaDevices) {
if (device instanceof BluetoothMediaDevice) { if (device instanceof BluetoothMediaDevice) {
if (isActiveDevice(((BluetoothMediaDevice) device).getCachedDevice())) { if (isActiveDevice(((BluetoothMediaDevice) device).getCachedDevice())) {
return device;
}
} else if (device instanceof PhoneMediaDevice) {
return device; return device;
} }
} else if (device instanceof PhoneMediaDevice) {
phoneMediaDevice = device;
} }
} }
return mMediaDevices.contains(phoneMediaDevice) ? phoneMediaDevice : null; Log.w(TAG, "updateCurrentConnectedDevice() can't found current connected device");
return null;
} }
private boolean isActiveDevice(CachedBluetoothDevice device) { private boolean isActiveDevice(CachedBluetoothDevice device) {
@@ -392,17 +409,26 @@ public class LocalMediaManager implements BluetoothCallback {
class MediaDeviceCallback implements MediaManager.MediaDeviceCallback { class MediaDeviceCallback implements MediaManager.MediaDeviceCallback {
@Override @Override
public void onDeviceAdded(MediaDevice device) { public void onDeviceAdded(MediaDevice device) {
if (!mMediaDevices.contains(device)) { boolean isAdded = false;
mMediaDevices.add(device); synchronized (mMediaDevicesLock) {
if (!mMediaDevices.contains(device)) {
mMediaDevices.add(device);
isAdded = true;
}
}
if (isAdded) {
dispatchDeviceListUpdate(); dispatchDeviceListUpdate();
} }
} }
@Override @Override
public void onDeviceListAdded(List<MediaDevice> devices) { public void onDeviceListAdded(List<MediaDevice> devices) {
mMediaDevices.clear(); synchronized (mMediaDevicesLock) {
mMediaDevices.addAll(devices); mMediaDevices.clear();
mMediaDevices.addAll(buildDisconnectedBluetoothDevice()); mMediaDevices.addAll(devices);
mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
}
final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice(); final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice();
mCurrentConnectedDevice = infoMediaDevice != null mCurrentConnectedDevice = infoMediaDevice != null
@@ -469,30 +495,42 @@ public class LocalMediaManager implements BluetoothCallback {
@Override @Override
public void onDeviceRemoved(MediaDevice device) { public void onDeviceRemoved(MediaDevice device) {
if (mMediaDevices.contains(device)) { boolean isRemoved = false;
mMediaDevices.remove(device); synchronized (mMediaDevicesLock) {
if (mMediaDevices.contains(device)) {
mMediaDevices.remove(device);
isRemoved = true;
}
}
if (isRemoved) {
dispatchDeviceListUpdate(); dispatchDeviceListUpdate();
} }
} }
@Override @Override
public void onDeviceListRemoved(List<MediaDevice> devices) { public void onDeviceListRemoved(List<MediaDevice> devices) {
mMediaDevices.removeAll(devices); synchronized (mMediaDevicesLock) {
mMediaDevices.removeAll(devices);
}
dispatchDeviceListUpdate(); dispatchDeviceListUpdate();
} }
@Override @Override
public void onConnectedDeviceChanged(String id) { public void onConnectedDeviceChanged(String id) {
MediaDevice connectDevice = getMediaDeviceById(mMediaDevices, id); MediaDevice connectDevice = null;
synchronized (mMediaDevicesLock) {
connectDevice = getMediaDeviceById(mMediaDevices, id);
}
connectDevice = connectDevice != null connectDevice = connectDevice != null
? connectDevice : updateCurrentConnectedDevice(); ? connectDevice : updateCurrentConnectedDevice();
if (connectDevice != null) {
connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
}
mCurrentConnectedDevice = connectDevice; mCurrentConnectedDevice = connectDevice;
dispatchSelectedDeviceStateChanged(mCurrentConnectedDevice, if (connectDevice != null) {
MediaDeviceState.STATE_CONNECTED); connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
dispatchSelectedDeviceStateChanged(mCurrentConnectedDevice,
MediaDeviceState.STATE_CONNECTED);
}
} }
@Override @Override
@@ -502,9 +540,11 @@ public class LocalMediaManager implements BluetoothCallback {
@Override @Override
public void onRequestFailed(int reason) { public void onRequestFailed(int reason) {
for (MediaDevice device : mMediaDevices) { synchronized (mMediaDevicesLock) {
if (device.getState() == MediaDeviceState.STATE_CONNECTING) { for (MediaDevice device : mMediaDevices) {
device.setState(MediaDeviceState.STATE_CONNECTING_FAILED); if (device.getState() == MediaDeviceState.STATE_CONNECTING) {
device.setState(MediaDeviceState.STATE_CONNECTING_FAILED);
}
} }
} }
dispatchOnRequestFailed(reason); dispatchOnRequestFailed(reason);