Add support for app route listing preferences
Test: atest MediaRouter2HostSideTest Bug: 241888071 Bug: 235352899 Change-Id: Ic9545a035631f2adb79d46e6432356dd7af4f5a0
This commit is contained in:
@@ -23507,6 +23507,7 @@ package android.media {
|
||||
method public void registerRouteCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RouteCallback, @NonNull android.media.RouteDiscoveryPreference);
|
||||
method public void registerTransferCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.TransferCallback);
|
||||
method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener);
|
||||
method public void setRouteListingPreference(@Nullable android.media.RouteListingPreference);
|
||||
method public void stop();
|
||||
method public void transferTo(@NonNull android.media.MediaRoute2Info);
|
||||
method public void unregisterControllerCallback(@NonNull android.media.MediaRouter2.ControllerCallback);
|
||||
@@ -23880,6 +23881,22 @@ package android.media {
|
||||
method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean);
|
||||
}
|
||||
|
||||
public final class RouteListingPreference implements android.os.Parcelable {
|
||||
ctor public RouteListingPreference(@NonNull java.util.List<android.media.RouteListingPreference.Item>);
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.List<android.media.RouteListingPreference.Item> getItems();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference> CREATOR;
|
||||
}
|
||||
|
||||
public static final class RouteListingPreference.Item implements android.os.Parcelable {
|
||||
ctor public RouteListingPreference.Item(@NonNull String);
|
||||
method public int describeContents();
|
||||
method @NonNull public String getRouteId();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR;
|
||||
}
|
||||
|
||||
public final class RoutingSessionInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public String getClientPackageName();
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.media;
|
||||
import android.media.MediaRoute2ProviderInfo;
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.media.RouteDiscoveryPreference;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.media.RoutingSessionInfo;
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,8 @@ oneway interface IMediaRouter2Manager {
|
||||
void notifySessionReleased(in RoutingSessionInfo session);
|
||||
void notifyDiscoveryPreferenceChanged(String packageName,
|
||||
in RouteDiscoveryPreference discoveryPreference);
|
||||
void notifyRouteListingPreferenceChange(String packageName,
|
||||
in @nullable RouteListingPreference routeListingPreference);
|
||||
void notifyRoutesUpdated(in List<MediaRoute2Info> routes);
|
||||
void notifyRequestFailed(int requestId, int reason);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.media.IMediaRouterClient;
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.media.MediaRouterClientState;
|
||||
import android.media.RouteDiscoveryPreference;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.media.RoutingSessionInfo;
|
||||
import android.os.Bundle;
|
||||
|
||||
@@ -57,6 +58,8 @@ interface IMediaRouterService {
|
||||
void unregisterRouter2(IMediaRouter2 router);
|
||||
void setDiscoveryRequestWithRouter2(IMediaRouter2 router,
|
||||
in RouteDiscoveryPreference preference);
|
||||
void setRouteListingPreference(IMediaRouter2 router,
|
||||
in @nullable RouteListingPreference routeListingPreference);
|
||||
void setRouteVolumeWithRouter2(IMediaRouter2 router, in MediaRoute2Info route, int volume);
|
||||
|
||||
void requestCreateSessionWithRouter2(IMediaRouter2 router, int requestId, long managerRequestId,
|
||||
|
||||
@@ -112,6 +112,10 @@ public final class MediaRouter2 {
|
||||
@GuardedBy("mLock")
|
||||
final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private RouteListingPreference mRouteListingPreference;
|
||||
|
||||
final RoutingController mSystemController;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -461,6 +465,52 @@ public final class MediaRouter2 {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link RouteListingPreference} of the app associated to this media router.
|
||||
*
|
||||
* <p>Use this method to inform the system UI of the routes that you would like to list for
|
||||
* media routing, via the Output Switcher.
|
||||
*
|
||||
* <p>You should call this method before {@link #registerRouteCallback registering any route
|
||||
* callbacks} and immediately after receiving any {@link RouteCallback#onRoutesUpdated route
|
||||
* updates} in order to keep the system UI in a consistent state. You can also call this method
|
||||
* at any other point to update the listing preference dynamically.
|
||||
*
|
||||
* <p>Notes:
|
||||
*
|
||||
* <ol>
|
||||
* <li>You should not include the ids of two or more routes with a match in their {@link
|
||||
* MediaRoute2Info#getDeduplicationIds() deduplication ids}. If you do, the system will
|
||||
* deduplicate them using its own criteria.
|
||||
* <li>You can use this method to rank routes in the output switcher, placing the more
|
||||
* important routes first. The system might override the proposed ranking.
|
||||
* <li>You can use this method to avoid listing routes using dynamic criteria. For example,
|
||||
* you can limit access to a specific type of device according to runtime criteria.
|
||||
* </ol>
|
||||
*
|
||||
* @param routeListingPreference The {@link RouteListingPreference} for the system to use for
|
||||
* route listing. When null, the system uses its default listing criteria.
|
||||
*/
|
||||
public void setRouteListingPreference(@Nullable RouteListingPreference routeListingPreference) {
|
||||
synchronized (mLock) {
|
||||
if (Objects.equals(mRouteListingPreference, routeListingPreference)) {
|
||||
// Nothing changed. We return early to save a call to the system server.
|
||||
return;
|
||||
}
|
||||
mRouteListingPreference = routeListingPreference;
|
||||
try {
|
||||
if (mStub == null) {
|
||||
MediaRouter2Stub stub = new MediaRouter2Stub();
|
||||
mMediaRouterService.registerRouter2(stub, mPackageName);
|
||||
mStub = stub;
|
||||
}
|
||||
mMediaRouterService.setRouteListingPreference(mStub, mRouteListingPreference);
|
||||
} catch (RemoteException ex) {
|
||||
ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean updateDiscoveryPreferenceIfNeededLocked() {
|
||||
RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -93,6 +94,11 @@ public final class MediaRouter2Manager {
|
||||
@NonNull
|
||||
final ConcurrentMap<String, RouteDiscoveryPreference> mDiscoveryPreferenceMap =
|
||||
new ConcurrentHashMap<>();
|
||||
// TODO(b/241888071): Merge mDiscoveryPreferenceMap and mPackageToRouteListingPreferenceMap into
|
||||
// a single record object maintained by a single package-to-record map.
|
||||
@NonNull
|
||||
private final ConcurrentMap<String, RouteListingPreference>
|
||||
mPackageToRouteListingPreferenceMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
|
||||
private final CopyOnWriteArrayList<TransferRequest> mTransferRequests =
|
||||
@@ -354,6 +360,16 @@ public final class MediaRouter2Manager {
|
||||
return mDiscoveryPreferenceMap.getOrDefault(packageName, RouteDiscoveryPreference.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RouteListingPreference} of the app with the given {@code packageName}, or
|
||||
* null if the app has not set any.
|
||||
*/
|
||||
@Nullable
|
||||
public RouteListingPreference getRouteListingPreference(@NonNull String packageName) {
|
||||
Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
|
||||
return mPackageToRouteListingPreferenceMap.get(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the system routing session for the given {@code packageName}.
|
||||
* Apps can select a route that is not the global route. (e.g. an app can select the device
|
||||
@@ -686,6 +702,24 @@ public final class MediaRouter2Manager {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRouteListingPreference(
|
||||
@NonNull String packageName, @Nullable RouteListingPreference routeListingPreference) {
|
||||
RouteListingPreference oldRouteListingPreference =
|
||||
routeListingPreference == null
|
||||
? mPackageToRouteListingPreferenceMap.remove(packageName)
|
||||
: mPackageToRouteListingPreferenceMap.put(
|
||||
packageName, routeListingPreference);
|
||||
if (Objects.equals(oldRouteListingPreference, routeListingPreference)) {
|
||||
return;
|
||||
}
|
||||
for (CallbackRecord record : mCallbackRecords) {
|
||||
record.mExecutor.execute(
|
||||
() ->
|
||||
record.mCallback.onRouteListingPreferenceUpdated(
|
||||
packageName, routeListingPreference));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unmodifiable list of selected routes for the session.
|
||||
*/
|
||||
@@ -970,6 +1004,19 @@ public final class MediaRouter2Manager {
|
||||
onPreferredFeaturesChanged(packageName, discoveryPreference.getPreferredFeatures());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the app with the given {@code packageName} updates its {@link
|
||||
* MediaRouter2#setRouteListingPreference route listing preference}.
|
||||
*
|
||||
* @param packageName The package name of the app that changed its listing preference.
|
||||
* @param routeListingPreference The new {@link RouteListingPreference} set by the app with
|
||||
* the given {@code packageName}. Maybe null if an app has unset its preference (by
|
||||
* passing null to {@link MediaRouter2#setRouteListingPreference}).
|
||||
*/
|
||||
default void onRouteListingPreferenceUpdated(
|
||||
@NonNull String packageName,
|
||||
@Nullable RouteListingPreference routeListingPreference) {}
|
||||
|
||||
/**
|
||||
* Called when a previous request has failed.
|
||||
*
|
||||
@@ -1055,6 +1102,17 @@ public final class MediaRouter2Manager {
|
||||
MediaRouter2Manager.this, packageName, discoveryPreference));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyRouteListingPreferenceChange(
|
||||
String packageName, @Nullable RouteListingPreference routeListingPreference) {
|
||||
mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
MediaRouter2Manager::updateRouteListingPreference,
|
||||
MediaRouter2Manager.this,
|
||||
packageName,
|
||||
routeListingPreference));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyRoutesUpdated(List<MediaRoute2Info> routes) {
|
||||
mHandler.sendMessage(
|
||||
|
||||
19
media/java/android/media/RouteListingPreference.aidl
Normal file
19
media/java/android/media/RouteListingPreference.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 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 android.media;
|
||||
|
||||
parcelable RouteListingPreference;
|
||||
183
media/java/android/media/RouteListingPreference.java
Normal file
183
media/java/android/media/RouteListingPreference.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 android.media;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Allows applications to customize the list of routes used for media routing (for example, in the
|
||||
* System UI Output Switcher).
|
||||
*
|
||||
* @see MediaRouter2#setRouteListingPreference
|
||||
*/
|
||||
public final class RouteListingPreference implements Parcelable {
|
||||
|
||||
@NonNull
|
||||
public static final Creator<RouteListingPreference> CREATOR =
|
||||
new Creator<>() {
|
||||
@Override
|
||||
public RouteListingPreference createFromParcel(Parcel in) {
|
||||
return new RouteListingPreference(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouteListingPreference[] newArray(int size) {
|
||||
return new RouteListingPreference[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull private final List<Item> mItems;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given values.
|
||||
*
|
||||
* @param items See {@link #getItems()}.
|
||||
*/
|
||||
public RouteListingPreference(@NonNull List<Item> items) {
|
||||
mItems = List.copyOf(Objects.requireNonNull(items));
|
||||
}
|
||||
|
||||
private RouteListingPreference(Parcel in) {
|
||||
List<Item> items =
|
||||
in.readParcelableList(new ArrayList<>(), Item.class.getClassLoader(), Item.class);
|
||||
mItems = List.copyOf(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list containing the items that the app wants to be listed for media
|
||||
* routing.
|
||||
*/
|
||||
@NonNull
|
||||
public List<Item> getItems() {
|
||||
return mItems;
|
||||
}
|
||||
|
||||
// RouteListingPreference Parcelable implementation.
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeParcelableList(mItems, flags);
|
||||
}
|
||||
|
||||
// Equals and hashCode.
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof RouteListingPreference)) {
|
||||
return false;
|
||||
}
|
||||
RouteListingPreference that = (RouteListingPreference) other;
|
||||
return mItems.equals(that.mItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mItems);
|
||||
}
|
||||
|
||||
// Internal classes.
|
||||
|
||||
/** Holds preference information for a specific route in a media routing listing. */
|
||||
public static final class Item implements Parcelable {
|
||||
|
||||
@NonNull
|
||||
public static final Creator<Item> CREATOR =
|
||||
new Creator<>() {
|
||||
@Override
|
||||
public Item createFromParcel(Parcel in) {
|
||||
return new Item(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item[] newArray(int size) {
|
||||
return new Item[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull private final String mRouteId;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given value.
|
||||
*
|
||||
* @param routeId See {@link #getRouteId()}. Must not be empty.
|
||||
*/
|
||||
public Item(@NonNull String routeId) {
|
||||
Preconditions.checkArgument(!TextUtils.isEmpty(routeId));
|
||||
mRouteId = routeId;
|
||||
}
|
||||
|
||||
private Item(Parcel in) {
|
||||
String routeId = in.readString();
|
||||
Preconditions.checkArgument(!TextUtils.isEmpty(routeId));
|
||||
mRouteId = routeId;
|
||||
}
|
||||
|
||||
/** Returns the id of the route that corresponds to this route listing preference item. */
|
||||
@NonNull
|
||||
public String getRouteId() {
|
||||
return mRouteId;
|
||||
}
|
||||
|
||||
// Item Parcelable implementation.
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString(mRouteId);
|
||||
}
|
||||
|
||||
// Equals and hashCode.
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof Item)) {
|
||||
return false;
|
||||
}
|
||||
Item item = (Item) other;
|
||||
return mRouteId.equals(item.mRouteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mRouteId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import android.media.MediaRoute2ProviderInfo;
|
||||
import android.media.MediaRoute2ProviderService;
|
||||
import android.media.MediaRouter2Manager;
|
||||
import android.media.RouteDiscoveryPreference;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.media.RoutingSessionInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -257,6 +258,24 @@ class MediaRouter2ServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public void setRouteListingPreference(
|
||||
@NonNull IMediaRouter2 router,
|
||||
@Nullable RouteListingPreference routeListingPreference) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
RouterRecord routerRecord = mAllRouterRecords.get(router.asBinder());
|
||||
if (routerRecord == null) {
|
||||
Slog.w(TAG, "Ignoring updating route listing of null routerRecord.");
|
||||
return;
|
||||
}
|
||||
setRouteListingPreferenceLocked(routerRecord, routeListingPreference);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRouteVolumeWithRouter2(@NonNull IMediaRouter2 router,
|
||||
@NonNull MediaRoute2Info route, int volume) {
|
||||
Objects.requireNonNull(router, "router must not be null");
|
||||
@@ -768,6 +787,31 @@ class MediaRouter2ServiceImpl {
|
||||
routerRecord.mUserRecord.mHandler));
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void setRouteListingPreferenceLocked(
|
||||
RouterRecord routerRecord, @Nullable RouteListingPreference routeListingPreference) {
|
||||
routerRecord.mRouteListingPreference = routeListingPreference;
|
||||
String routeListingAsString =
|
||||
routeListingPreference != null
|
||||
? routeListingPreference.getItems().stream()
|
||||
.map(RouteListingPreference.Item::getRouteId)
|
||||
.collect(Collectors.joining(","))
|
||||
: null;
|
||||
mEventLogger.enqueue(
|
||||
EventLogger.StringEvent.from(
|
||||
"setRouteListingPreference",
|
||||
"router id: %d, route listing preference: [%s]",
|
||||
routerRecord.mRouterId,
|
||||
routeListingAsString));
|
||||
|
||||
routerRecord.mUserRecord.mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
UserHandler::notifyRouteListingPreferenceChangeToManagers,
|
||||
routerRecord.mUserRecord.mHandler,
|
||||
routerRecord.mPackageName,
|
||||
routeListingPreference));
|
||||
}
|
||||
|
||||
private void setRouteVolumeWithRouter2Locked(@NonNull IMediaRouter2 router,
|
||||
@NonNull MediaRoute2Info route, int volume) {
|
||||
final IBinder binder = router.asBinder();
|
||||
@@ -1018,6 +1062,15 @@ class MediaRouter2ServiceImpl {
|
||||
// RouteCallback#onRoutesAdded() for system MR2 will never be called with initial routes
|
||||
// due to the lack of features.
|
||||
for (RouterRecord routerRecord : userRecord.mRouterRecords) {
|
||||
// Send route listing preferences before discovery preferences and routes to avoid an
|
||||
// inconsistent state where there are routes to show, but the manager thinks
|
||||
// the app has not expressed a preference for listing.
|
||||
userRecord.mHandler.sendMessage(
|
||||
obtainMessage(
|
||||
UserHandler::notifyRouteListingPreferenceChangeToManagers,
|
||||
routerRecord.mUserRecord.mHandler,
|
||||
routerRecord.mPackageName,
|
||||
routerRecord.mRouteListingPreference));
|
||||
// TODO: UserRecord <-> routerRecord, why do they reference each other?
|
||||
// How about removing mUserRecord from routerRecord?
|
||||
routerRecord.mUserRecord.mHandler.sendMessage(
|
||||
@@ -1397,6 +1450,7 @@ class MediaRouter2ServiceImpl {
|
||||
public final int mRouterId;
|
||||
|
||||
public RouteDiscoveryPreference mDiscoveryPreference;
|
||||
@Nullable public RouteListingPreference mRouteListingPreference;
|
||||
|
||||
RouterRecord(UserRecord userRecord, IMediaRouter2 router, int uid, int pid,
|
||||
String packageName, boolean hasConfigureWifiDisplayPermission,
|
||||
@@ -2424,6 +2478,34 @@ class MediaRouter2ServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRouteListingPreferenceChangeToManagers(
|
||||
String routerPackageName, @Nullable RouteListingPreference routeListingPreference) {
|
||||
MediaRouter2ServiceImpl service = mServiceRef.get();
|
||||
if (service == null) {
|
||||
return;
|
||||
}
|
||||
List<IMediaRouter2Manager> managers = new ArrayList<>();
|
||||
synchronized (service.mLock) {
|
||||
for (ManagerRecord managerRecord : mUserRecord.mManagerRecords) {
|
||||
managers.add(managerRecord.mManager);
|
||||
}
|
||||
}
|
||||
for (IMediaRouter2Manager manager : managers) {
|
||||
try {
|
||||
manager.notifyRouteListingPreferenceChange(
|
||||
routerPackageName, routeListingPreference);
|
||||
} catch (RemoteException ex) {
|
||||
Slog.w(
|
||||
TAG,
|
||||
"Failed to notify preferred features changed."
|
||||
+ " Manager probably died.",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
// TODO(b/238178508): In order to support privileged media router instances, we also
|
||||
// need to update routers other than the one making the update.
|
||||
}
|
||||
|
||||
private void notifyRequestFailedToManager(@NonNull IMediaRouter2Manager manager,
|
||||
int requestId, int reason) {
|
||||
try {
|
||||
@@ -2505,7 +2587,6 @@ class MediaRouter2ServiceImpl {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
static final class SessionCreationRequest {
|
||||
public final RouterRecord mRouterRecord;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.media;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.UserSwitchObserver;
|
||||
@@ -43,6 +44,7 @@ import android.media.MediaRouterClientState;
|
||||
import android.media.RemoteDisplayState;
|
||||
import android.media.RemoteDisplayState.RemoteDisplayInfo;
|
||||
import android.media.RouteDiscoveryPreference;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.media.RoutingSessionInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -418,6 +420,14 @@ public final class MediaRouterService extends IMediaRouterService.Stub
|
||||
mService2.setDiscoveryRequestWithRouter2(router, request);
|
||||
}
|
||||
|
||||
// Binder call
|
||||
@Override
|
||||
public void setRouteListingPreference(
|
||||
@NonNull IMediaRouter2 router,
|
||||
@Nullable RouteListingPreference routeListingPreference) {
|
||||
mService2.setRouteListingPreference(router, routeListingPreference);
|
||||
}
|
||||
|
||||
// Binder call
|
||||
@Override
|
||||
public void setRouteVolumeWithRouter2(IMediaRouter2 router,
|
||||
|
||||
Reference in New Issue
Block a user