Remove code duplications
Also prevent callback be called before SysMRP created Test: pass MediaRouter cts Change-Id: I0cde791fc73a33de5d42dcb6e550016644301ffd
This commit is contained in:
@@ -166,6 +166,20 @@ class BluetoothRouteProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
MediaRoute2Info getSelectedRoute() {
|
||||
return (mSelectedRoute == null) ? null : mSelectedRoute.route;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
List<MediaRoute2Info> getTransferableRoutes() {
|
||||
List<MediaRoute2Info> routes = getAllBluetoothRoutes();
|
||||
if (mSelectedRoute != null) {
|
||||
routes.remove(mSelectedRoute.route);
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
List<MediaRoute2Info> getAllBluetoothRoutes() {
|
||||
ArrayList<MediaRoute2Info> routes = new ArrayList<>();
|
||||
@@ -175,9 +189,12 @@ class BluetoothRouteProvider {
|
||||
return routes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getSelectedRouteId() {
|
||||
return mSelectedRoute == null ? null : mSelectedRoute.route.getId();
|
||||
boolean setSelectedRouteVolume(int volume) {
|
||||
if (mSelectedRoute == null) return false;
|
||||
mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route)
|
||||
.setVolume(volume)
|
||||
.build();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void notifyBluetoothRoutesUpdated() {
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.server.media;
|
||||
import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
|
||||
import static android.media.MediaRoute2Info.FEATURE_LIVE_VIDEO;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -42,15 +41,13 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Provides routes for local playbacks such as phone speaker, wired headset, or Bluetooth speakers.
|
||||
*/
|
||||
// TODO: check thread safety. We may need to use lock to protect variables.
|
||||
class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
private static final String TAG = "MR2SystemProvider";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
@@ -68,19 +65,16 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
SystemMediaRoute2Provider.class.getPackageName$(),
|
||||
SystemMediaRoute2Provider.class.getName());
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private String mSelectedRouteId;
|
||||
MediaRoute2Info mDefaultRoute;
|
||||
@NonNull List<MediaRoute2Info> mBluetoothRoutes = Collections.EMPTY_LIST;
|
||||
final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
|
||||
|
||||
final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
|
||||
@Override
|
||||
public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
updateAudioRoutes(newRoutes);
|
||||
}
|
||||
mHandler.post(() -> {
|
||||
updateDefaultRoute(newRoutes);
|
||||
notifyProviderState();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -97,11 +91,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mAudioService = IAudioService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.AUDIO_SERVICE));
|
||||
AudioRoutesInfo newAudioRoutes = null;
|
||||
try {
|
||||
newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
updateDefaultRoute(newAudioRoutes);
|
||||
|
||||
initializeDefaultRoute();
|
||||
mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> {
|
||||
mBluetoothRoutes = routes;
|
||||
publishRoutes();
|
||||
publishProviderState();
|
||||
|
||||
boolean sessionInfoChanged;
|
||||
synchronized (mLock) {
|
||||
@@ -111,7 +109,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
notifySessionInfoUpdated();
|
||||
}
|
||||
});
|
||||
initializeSessionInfo();
|
||||
|
||||
mHandler.post(() -> notifyProviderState());
|
||||
|
||||
//TODO: clean up this
|
||||
// This is required because it is not instantiated in the main thread and
|
||||
// BluetoothRoutesUpdatedListener can be called before here
|
||||
synchronized (mLock) {
|
||||
updateSessionInfosIfNeededLocked();
|
||||
}
|
||||
|
||||
mContext.registerReceiver(new VolumeChangeReceiver(),
|
||||
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
|
||||
@@ -164,65 +170,21 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
// Do nothing since we don't support grouping volume yet.
|
||||
}
|
||||
|
||||
private void initializeDefaultRoute() {
|
||||
mDefaultRoute = new MediaRoute2Info.Builder(
|
||||
DEFAULT_ROUTE_ID,
|
||||
mContext.getResources().getText(R.string.default_audio_route_name).toString())
|
||||
.setVolumeHandling(mAudioManager.isVolumeFixed()
|
||||
? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
|
||||
: MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
|
||||
.setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
|
||||
.setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
|
||||
.addFeature(FEATURE_LIVE_AUDIO)
|
||||
.addFeature(FEATURE_LIVE_VIDEO)
|
||||
.build();
|
||||
|
||||
AudioRoutesInfo newAudioRoutes = null;
|
||||
try {
|
||||
newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
if (newAudioRoutes != null) {
|
||||
// This will select the active BT route if there is one and the current
|
||||
// selected route is the default system route, or if there is no selected
|
||||
// route yet.
|
||||
updateAudioRoutes(newAudioRoutes);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeSessionInfo() {
|
||||
mBluetoothRoutes = mBtRouteProvider.getAllBluetoothRoutes();
|
||||
|
||||
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
|
||||
builder.addRoute(mDefaultRoute);
|
||||
for (MediaRoute2Info route : mBluetoothRoutes) {
|
||||
builder.addRoute(route);
|
||||
}
|
||||
setProviderState(builder.build());
|
||||
mHandler.post(() -> notifyProviderState());
|
||||
|
||||
//TODO: clean up this
|
||||
// This is required because it is not instantiated in the main thread and
|
||||
// BluetoothRoutesUpdatedListener can be called before this function
|
||||
synchronized (mLock) {
|
||||
updateSessionInfosIfNeededLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAudioRoutes(AudioRoutesInfo newRoutes) {
|
||||
private void updateDefaultRoute(AudioRoutesInfo newRoutes) {
|
||||
int name = R.string.default_audio_route_name;
|
||||
mCurAudioRoutesInfo.mainType = newRoutes.mainType;
|
||||
if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0
|
||||
|| (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_headphones;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_hdmi;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_usb;
|
||||
if (newRoutes != null) {
|
||||
mCurAudioRoutesInfo.mainType = newRoutes.mainType;
|
||||
if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0
|
||||
|| (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_headphones;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HDMI) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_hdmi;
|
||||
} else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_USB) != 0) {
|
||||
name = com.android.internal.R.string.default_audio_route_name_usb;
|
||||
}
|
||||
}
|
||||
|
||||
mDefaultRoute = new MediaRoute2Info.Builder(
|
||||
DEFAULT_ROUTE_ID, mContext.getResources().getText(name).toString())
|
||||
.setVolumeHandling(mAudioManager.isVolumeFixed()
|
||||
@@ -232,9 +194,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
.setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
|
||||
.addFeature(FEATURE_LIVE_AUDIO)
|
||||
.addFeature(FEATURE_LIVE_VIDEO)
|
||||
.setConnectionState(MediaRoute2Info.CONNECTION_STATE_CONNECTED)
|
||||
.build();
|
||||
updateProviderState();
|
||||
}
|
||||
|
||||
publishRoutes();
|
||||
private void updateProviderState() {
|
||||
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
|
||||
builder.addRoute(mDefaultRoute);
|
||||
if (mBtRouteProvider != null) {
|
||||
for (MediaRoute2Info route : mBtRouteProvider.getAllBluetoothRoutes()) {
|
||||
builder.addRoute(route);
|
||||
}
|
||||
}
|
||||
setProviderState(builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,21 +219,21 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
|
||||
SYSTEM_SESSION_ID, "" /* clientPackageName */)
|
||||
.setSystemSession(true);
|
||||
String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId();
|
||||
mSelectedRouteId = TextUtils.isEmpty(activeBtDeviceAddress) ? mDefaultRoute.getId()
|
||||
: activeBtDeviceAddress;
|
||||
builder.addSelectedRoute(mSelectedRouteId);
|
||||
|
||||
if (!TextUtils.isEmpty(activeBtDeviceAddress)) {
|
||||
MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute();
|
||||
if (selectedRoute == null) {
|
||||
selectedRoute = mDefaultRoute;
|
||||
} else {
|
||||
builder.addTransferableRoute(mDefaultRoute.getId());
|
||||
}
|
||||
mSelectedRouteId = selectedRoute.getId();
|
||||
builder.addSelectedRoute(mSelectedRouteId);
|
||||
|
||||
for (MediaRoute2Info route : mBluetoothRoutes) {
|
||||
if (!TextUtils.equals(mSelectedRouteId, route.getId())) {
|
||||
builder.addTransferableRoute(route.getId());
|
||||
}
|
||||
for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) {
|
||||
builder.addTransferableRoute(route.getId());
|
||||
}
|
||||
|
||||
|
||||
RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build();
|
||||
if (Objects.equals(oldSessionInfo, newSessionInfo)) {
|
||||
return false;
|
||||
@@ -271,13 +244,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
}
|
||||
}
|
||||
|
||||
void publishRoutes() {
|
||||
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
|
||||
builder.addRoute(mDefaultRoute);
|
||||
for (MediaRoute2Info route : mBluetoothRoutes) {
|
||||
builder.addRoute(route);
|
||||
}
|
||||
setAndNotifyProviderState(builder.build());
|
||||
void publishProviderState() {
|
||||
updateProviderState();
|
||||
notifyProviderState();
|
||||
}
|
||||
|
||||
void notifySessionInfoUpdated() {
|
||||
@@ -306,24 +275,14 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
|
||||
AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
|
||||
|
||||
if (newVolume != oldVolume) {
|
||||
String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId();
|
||||
if (!TextUtils.isEmpty(activeBtDeviceAddress)) {
|
||||
for (int i = mBluetoothRoutes.size() - 1; i >= 0; i--) {
|
||||
MediaRoute2Info route = mBluetoothRoutes.get(i);
|
||||
if (TextUtils.equals(activeBtDeviceAddress, route.getId())) {
|
||||
mBluetoothRoutes.set(i,
|
||||
new MediaRoute2Info.Builder(route)
|
||||
.setVolume(newVolume)
|
||||
.build());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (TextUtils.equals(mDefaultRoute.getId(), mSelectedRouteId)) {
|
||||
mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute)
|
||||
.setVolume(newVolume)
|
||||
.build();
|
||||
} else {
|
||||
mBtRouteProvider.setSelectedRouteVolume(newVolume);
|
||||
}
|
||||
publishRoutes();
|
||||
publishProviderState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user