Loading media/java/android/media/MediaRoute2ProviderInfo.java +3 −2 Original line number Diff line number Diff line Loading @@ -46,9 +46,9 @@ public final class MediaRoute2ProviderInfo implements Parcelable { }; @Nullable private final String mUniqueId; final String mUniqueId; @NonNull private final ArrayMap<String, MediaRoute2Info> mRoutes; final ArrayMap<String, MediaRoute2Info> mRoutes; MediaRoute2ProviderInfo(@NonNull Builder builder) { Objects.requireNonNull(builder, "builder must not be null."); Loading Loading @@ -142,6 +142,7 @@ public final class MediaRoute2ProviderInfo implements Parcelable { public Builder(@NonNull MediaRoute2ProviderInfo descriptor) { Objects.requireNonNull(descriptor, "descriptor must not be null"); mUniqueId = descriptor.mUniqueId; mRoutes = new ArrayMap<>(descriptor.mRoutes); } Loading media/java/android/media/MediaRoute2ProviderService.java +174 −14 Original line number Diff line number Diff line Loading @@ -27,8 +27,13 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** Loading @@ -40,10 +45,14 @@ public abstract class MediaRoute2ProviderService extends Service { public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService"; private final Handler mHandler; private final Object mSessionLock = new Object(); private ProviderStub mStub; private IMediaRoute2ProviderClient mClient; private MediaRoute2ProviderInfo mProviderInfo; @GuardedBy("mSessionLock") private ArrayMap<Integer, RouteSessionInfo> mSessionInfo = new ArrayMap<>(); public MediaRoute2ProviderService() { mHandler = new Handler(Looper.getMainLooper()); } Loading Loading @@ -93,6 +102,7 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when requestSetVolume is called on a route of the provider * * @param routeId the id of the route * @param volume the target volume */ Loading @@ -100,15 +110,164 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when requestUpdateVolume is called on a route of the provider * * @param routeId id of the route * @param delta the delta to add to the current volume */ public abstract void onUpdateVolume(@NonNull String routeId, int delta); /** * Updates provider info and publishes routes * Gets information of the session with the given id. * * @param sessionId id of the session * @return information of the session with the given id. * null if the session is destroyed or id is not valid. */ @Nullable public final RouteSessionInfo getSessionInfo(int sessionId) { synchronized (mSessionLock) { return mSessionInfo.get(sessionId); } } /** * Gets the list of {@link RouteSessionInfo session info} that the provider service maintains. */ @NonNull public final List<RouteSessionInfo> getAllSessionInfo() { synchronized (mSessionLock) { return new ArrayList<>(mSessionInfo.values()); } } /** * Sets the information of the session with the given id. * If there is no session matched with the given id, it will be ignored. * A session will be destroyed if it has no selected route. * Call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify clients of * session info changes. * * @param sessionId id of the session that should update its information * @param sessionInfo new session information */ public final void setSessionInfo(int sessionId, @NonNull RouteSessionInfo sessionInfo) { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { mSessionInfo.put(sessionId, sessionInfo); } else { Log.w(TAG, "Ignoring session info update."); } } } /** * Notifies clients of that the session is created and ready for use. If the session can be * controlled, pass a {@link Bundle} that contains how to control it. * * @param sessionId id of the session * @param sessionInfo information of the new session. * Pass {@code null} to reject the request or inform clients that * session creation has failed. * @param controlHints a {@link Bundle} that contains how to control the session. */ //TODO: fail reason? public final void notifySessionCreated(int sessionId, @Nullable RouteSessionInfo sessionInfo, @Nullable Bundle controlHints) { //TODO: validate sessionId (it must be in "waiting list") synchronized (mSessionLock) { mSessionInfo.put(sessionId, sessionInfo); //TODO: notify media router service of session creation. } } /** * Releases a session with the given id. * {@link #onDestroySession} is called if the session is released. * * @param sessionId id of the session to be released * @see #onDestroySession(int, RouteSessionInfo) */ public final void setProviderInfo(MediaRoute2ProviderInfo info) { public final void releaseSession(int sessionId) { RouteSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.put(sessionId, null); } if (sessionInfo != null) { mHandler.sendMessage(obtainMessage( MediaRoute2ProviderService::onDestroySession, this, sessionId, sessionInfo)); } } /** * Called when a session should be created. * You should create and maintain your own session and notifies the client of * session info. Call {@link #notifySessionCreated(int, RouteSessionInfo, Bundle)} * to notify the information of a new session. * If you can't create the session or want to reject the request, pass {@code null} * as session info in {@link #notifySessionCreated(int, RouteSessionInfo, Bundle)}. * * @param packageName the package name of the application that selected the route * @param routeId the id of the route initially being connected * @param controlCategory the control category of the new session * @param sessionId the id of a new session */ public abstract void onCreateSession(@NonNull String packageName, @NonNull String routeId, @NonNull String controlCategory, int sessionId); /** * Called when a session is about to be destroyed. * You can clean up your session here. This can happen by the * client or provider itself. * * @param sessionId id of the session being destroyed. * @param lastSessionInfo information of the session being destroyed. * @see #releaseSession(int) */ public abstract void onDestroySession(int sessionId, @NonNull RouteSessionInfo lastSessionInfo); //TODO: make a way to reject the request /** * Called when a client requests adding a route to a session. * After the route is added, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route * @see #setSessionInfo(int, RouteSessionInfo) */ public abstract void onAddRoute(int sessionId, @NonNull String routeId); //TODO: make a way to reject the request /** * Called when a client requests removing a route from a session. * After the route is removed, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route */ public abstract void onRemoveRoute(int sessionId, @NonNull String routeId); //TODO: make a way to reject the request /** * Called when a client requests transferring a session to a route. * After the transfer is finished, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route */ public abstract void onTransferRoute(int sessionId, @NonNull String routeId); /** * Updates provider info and publishes routes and session info. */ public final void updateProviderInfo(MediaRoute2ProviderInfo info) { mProviderInfo = info; publishState(); } Loading Loading @@ -142,6 +301,7 @@ public abstract class MediaRoute2ProviderService extends Service { } void publishState() { //TODO: sends session info if (mClient == null) { return; } Loading Loading @@ -179,35 +339,35 @@ public abstract class MediaRoute2ProviderService extends Service { } @Override public void requestSelectRoute(String packageName, String id, int seq) { public void requestSelectRoute(String packageName, String routeId, int seq) { //TODO: call onCreateSession instead mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, MediaRoute2ProviderService.this, packageName, id, new SelectToken(packageName, id, seq))); MediaRoute2ProviderService.this, packageName, routeId, new SelectToken(packageName, routeId, seq))); } @Override public void unselectRoute(String packageName, String id) { public void unselectRoute(String packageName, String routeId) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUnselectRoute, MediaRoute2ProviderService.this, packageName, id)); MediaRoute2ProviderService.this, packageName, routeId)); } @Override public void notifyControlRequestSent(String id, Intent request) { public void notifyControlRequestSent(String routeId, Intent request) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest, MediaRoute2ProviderService.this, id, request)); MediaRoute2ProviderService.this, routeId, request)); } @Override public void requestSetVolume(String id, int volume) { public void requestSetVolume(String routeId, int volume) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetVolume, MediaRoute2ProviderService.this, id, volume)); MediaRoute2ProviderService.this, routeId, volume)); } @Override public void requestUpdateVolume(String id, int delta) { public void requestUpdateVolume(String routeId, int delta) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUpdateVolume, MediaRoute2ProviderService.this, id, delta)); MediaRoute2ProviderService.this, routeId, delta)); } } } media/java/android/media/RouteSessionInfo.java +62 −25 Original line number Diff line number Diff line Loading @@ -218,79 +218,116 @@ public class RouteSessionInfo implements Parcelable { } /** * Adds a selected route * Clears the selected routes. */ @NonNull public Builder addSelectedRoute(String routeId) { mSelectedRoutes.add(routeId); public Builder clearSelectedRoutes() { mSelectedRoutes.clear(); return this; } /** * Removes a selected route * Adds a route to the selected routes. */ @NonNull public Builder removeSelectedRoute(String routeId) { mSelectedRoutes.remove(routeId); public Builder addSelectedRoute(@NonNull String routeId) { mSelectedRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Adds a deselectable route * Removes a route from the selected routes. */ @NonNull public Builder addDeselectableRoute(String routeId) { mDeselectableRoutes.add(routeId); public Builder removeSelectedRoute(@NonNull String routeId) { mSelectedRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a deselecable route * Clears the deselectable routes. */ @NonNull public Builder removeDeselectableRoute(String routeId) { mDeselectableRoutes.remove(routeId); public Builder clearDeselectableRoutes() { mDeselectableRoutes.clear(); return this; } /** * Adds a groupable route * Adds a route to the deselectable routes. */ @NonNull public Builder addGroupableRoute(String routeId) { mGroupableRoutes.add(routeId); public Builder addDeselectableRoute(@NonNull String routeId) { mDeselectableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a groupable route * Removes a route from the deselectable routes. */ @NonNull public Builder removeGroupableRoute(String routeId) { mGroupableRoutes.remove(routeId); public Builder removeDeselectableRoute(@NonNull String routeId) { mDeselectableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Adds a transferrable route * Clears the groupable routes. */ @NonNull public Builder addTransferrableRoute(String routeId) { mTransferrableRoutes.add(routeId); public Builder clearGroupableRoutes() { mGroupableRoutes.clear(); return this; } /** * Removes a transferrable route * Adds a route to the groupable routes. */ @NonNull public Builder removeTransferrableRoute(String routeId) { mTransferrableRoutes.remove(routeId); public Builder addGroupableRoute(@NonNull String routeId) { mGroupableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Builds a route session info * Removes a route from the groupable routes. */ @NonNull public Builder removeGroupableRoute(@NonNull String routeId) { mGroupableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Clears the transferrable routes. */ @NonNull public Builder clearTransferrableRoutes() { mTransferrableRoutes.clear(); return this; } /** * Adds a route to the transferrable routes. */ @NonNull public Builder addTransferrableRoute(@NonNull String routeId) { mTransferrableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a route from the transferrable routes. */ @NonNull public Builder removeTransferrableRoute(@NonNull String routeId) { mTransferrableRoutes.remove( Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Builds a route session info. */ @NonNull public RouteSessionInfo build() { Loading media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java +47 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Intent; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2ProviderService; import android.media.RouteSessionInfo; import android.os.Bundle; import android.os.IBinder; Loading Loading @@ -159,10 +160,55 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService publishRoutes(); } @Override public void onCreateSession(String packageName, String routeId, String controlCategory, int sessionId) { RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( sessionId, packageName, controlCategory) .addSelectedRoute(routeId) .build(); notifySessionCreated(sessionId, sessionInfo, null); } @Override public void onDestroySession(int sessionId, RouteSessionInfo lastSessionInfo) {} @Override public void onAddRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); //TODO: we may want to remove route if it belongs to another session RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .addSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } @Override public void onRemoveRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .removeSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } @Override public void onTransferRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .clearSelectedRoutes() .addSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } void publishRoutes() { MediaRoute2ProviderInfo info = new MediaRoute2ProviderInfo.Builder() .addRoutes(mRoutes.values()) .build(); setProviderInfo(info); updateProviderInfo(info); } } Loading
media/java/android/media/MediaRoute2ProviderInfo.java +3 −2 Original line number Diff line number Diff line Loading @@ -46,9 +46,9 @@ public final class MediaRoute2ProviderInfo implements Parcelable { }; @Nullable private final String mUniqueId; final String mUniqueId; @NonNull private final ArrayMap<String, MediaRoute2Info> mRoutes; final ArrayMap<String, MediaRoute2Info> mRoutes; MediaRoute2ProviderInfo(@NonNull Builder builder) { Objects.requireNonNull(builder, "builder must not be null."); Loading Loading @@ -142,6 +142,7 @@ public final class MediaRoute2ProviderInfo implements Parcelable { public Builder(@NonNull MediaRoute2ProviderInfo descriptor) { Objects.requireNonNull(descriptor, "descriptor must not be null"); mUniqueId = descriptor.mUniqueId; mRoutes = new ArrayMap<>(descriptor.mRoutes); } Loading
media/java/android/media/MediaRoute2ProviderService.java +174 −14 Original line number Diff line number Diff line Loading @@ -27,8 +27,13 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** Loading @@ -40,10 +45,14 @@ public abstract class MediaRoute2ProviderService extends Service { public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService"; private final Handler mHandler; private final Object mSessionLock = new Object(); private ProviderStub mStub; private IMediaRoute2ProviderClient mClient; private MediaRoute2ProviderInfo mProviderInfo; @GuardedBy("mSessionLock") private ArrayMap<Integer, RouteSessionInfo> mSessionInfo = new ArrayMap<>(); public MediaRoute2ProviderService() { mHandler = new Handler(Looper.getMainLooper()); } Loading Loading @@ -93,6 +102,7 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when requestSetVolume is called on a route of the provider * * @param routeId the id of the route * @param volume the target volume */ Loading @@ -100,15 +110,164 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when requestUpdateVolume is called on a route of the provider * * @param routeId id of the route * @param delta the delta to add to the current volume */ public abstract void onUpdateVolume(@NonNull String routeId, int delta); /** * Updates provider info and publishes routes * Gets information of the session with the given id. * * @param sessionId id of the session * @return information of the session with the given id. * null if the session is destroyed or id is not valid. */ @Nullable public final RouteSessionInfo getSessionInfo(int sessionId) { synchronized (mSessionLock) { return mSessionInfo.get(sessionId); } } /** * Gets the list of {@link RouteSessionInfo session info} that the provider service maintains. */ @NonNull public final List<RouteSessionInfo> getAllSessionInfo() { synchronized (mSessionLock) { return new ArrayList<>(mSessionInfo.values()); } } /** * Sets the information of the session with the given id. * If there is no session matched with the given id, it will be ignored. * A session will be destroyed if it has no selected route. * Call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify clients of * session info changes. * * @param sessionId id of the session that should update its information * @param sessionInfo new session information */ public final void setSessionInfo(int sessionId, @NonNull RouteSessionInfo sessionInfo) { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { mSessionInfo.put(sessionId, sessionInfo); } else { Log.w(TAG, "Ignoring session info update."); } } } /** * Notifies clients of that the session is created and ready for use. If the session can be * controlled, pass a {@link Bundle} that contains how to control it. * * @param sessionId id of the session * @param sessionInfo information of the new session. * Pass {@code null} to reject the request or inform clients that * session creation has failed. * @param controlHints a {@link Bundle} that contains how to control the session. */ //TODO: fail reason? public final void notifySessionCreated(int sessionId, @Nullable RouteSessionInfo sessionInfo, @Nullable Bundle controlHints) { //TODO: validate sessionId (it must be in "waiting list") synchronized (mSessionLock) { mSessionInfo.put(sessionId, sessionInfo); //TODO: notify media router service of session creation. } } /** * Releases a session with the given id. * {@link #onDestroySession} is called if the session is released. * * @param sessionId id of the session to be released * @see #onDestroySession(int, RouteSessionInfo) */ public final void setProviderInfo(MediaRoute2ProviderInfo info) { public final void releaseSession(int sessionId) { RouteSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.put(sessionId, null); } if (sessionInfo != null) { mHandler.sendMessage(obtainMessage( MediaRoute2ProviderService::onDestroySession, this, sessionId, sessionInfo)); } } /** * Called when a session should be created. * You should create and maintain your own session and notifies the client of * session info. Call {@link #notifySessionCreated(int, RouteSessionInfo, Bundle)} * to notify the information of a new session. * If you can't create the session or want to reject the request, pass {@code null} * as session info in {@link #notifySessionCreated(int, RouteSessionInfo, Bundle)}. * * @param packageName the package name of the application that selected the route * @param routeId the id of the route initially being connected * @param controlCategory the control category of the new session * @param sessionId the id of a new session */ public abstract void onCreateSession(@NonNull String packageName, @NonNull String routeId, @NonNull String controlCategory, int sessionId); /** * Called when a session is about to be destroyed. * You can clean up your session here. This can happen by the * client or provider itself. * * @param sessionId id of the session being destroyed. * @param lastSessionInfo information of the session being destroyed. * @see #releaseSession(int) */ public abstract void onDestroySession(int sessionId, @NonNull RouteSessionInfo lastSessionInfo); //TODO: make a way to reject the request /** * Called when a client requests adding a route to a session. * After the route is added, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route * @see #setSessionInfo(int, RouteSessionInfo) */ public abstract void onAddRoute(int sessionId, @NonNull String routeId); //TODO: make a way to reject the request /** * Called when a client requests removing a route from a session. * After the route is removed, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route */ public abstract void onRemoveRoute(int sessionId, @NonNull String routeId); //TODO: make a way to reject the request /** * Called when a client requests transferring a session to a route. * After the transfer is finished, call {@link #setSessionInfo(int, RouteSessionInfo)} to update * session info and call {@link #updateProviderInfo(MediaRoute2ProviderInfo)} to notify * clients of updated session info. * * @param sessionId id of the session * @param routeId id of the route */ public abstract void onTransferRoute(int sessionId, @NonNull String routeId); /** * Updates provider info and publishes routes and session info. */ public final void updateProviderInfo(MediaRoute2ProviderInfo info) { mProviderInfo = info; publishState(); } Loading Loading @@ -142,6 +301,7 @@ public abstract class MediaRoute2ProviderService extends Service { } void publishState() { //TODO: sends session info if (mClient == null) { return; } Loading Loading @@ -179,35 +339,35 @@ public abstract class MediaRoute2ProviderService extends Service { } @Override public void requestSelectRoute(String packageName, String id, int seq) { public void requestSelectRoute(String packageName, String routeId, int seq) { //TODO: call onCreateSession instead mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, MediaRoute2ProviderService.this, packageName, id, new SelectToken(packageName, id, seq))); MediaRoute2ProviderService.this, packageName, routeId, new SelectToken(packageName, routeId, seq))); } @Override public void unselectRoute(String packageName, String id) { public void unselectRoute(String packageName, String routeId) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUnselectRoute, MediaRoute2ProviderService.this, packageName, id)); MediaRoute2ProviderService.this, packageName, routeId)); } @Override public void notifyControlRequestSent(String id, Intent request) { public void notifyControlRequestSent(String routeId, Intent request) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest, MediaRoute2ProviderService.this, id, request)); MediaRoute2ProviderService.this, routeId, request)); } @Override public void requestSetVolume(String id, int volume) { public void requestSetVolume(String routeId, int volume) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetVolume, MediaRoute2ProviderService.this, id, volume)); MediaRoute2ProviderService.this, routeId, volume)); } @Override public void requestUpdateVolume(String id, int delta) { public void requestUpdateVolume(String routeId, int delta) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUpdateVolume, MediaRoute2ProviderService.this, id, delta)); MediaRoute2ProviderService.this, routeId, delta)); } } }
media/java/android/media/RouteSessionInfo.java +62 −25 Original line number Diff line number Diff line Loading @@ -218,79 +218,116 @@ public class RouteSessionInfo implements Parcelable { } /** * Adds a selected route * Clears the selected routes. */ @NonNull public Builder addSelectedRoute(String routeId) { mSelectedRoutes.add(routeId); public Builder clearSelectedRoutes() { mSelectedRoutes.clear(); return this; } /** * Removes a selected route * Adds a route to the selected routes. */ @NonNull public Builder removeSelectedRoute(String routeId) { mSelectedRoutes.remove(routeId); public Builder addSelectedRoute(@NonNull String routeId) { mSelectedRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Adds a deselectable route * Removes a route from the selected routes. */ @NonNull public Builder addDeselectableRoute(String routeId) { mDeselectableRoutes.add(routeId); public Builder removeSelectedRoute(@NonNull String routeId) { mSelectedRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a deselecable route * Clears the deselectable routes. */ @NonNull public Builder removeDeselectableRoute(String routeId) { mDeselectableRoutes.remove(routeId); public Builder clearDeselectableRoutes() { mDeselectableRoutes.clear(); return this; } /** * Adds a groupable route * Adds a route to the deselectable routes. */ @NonNull public Builder addGroupableRoute(String routeId) { mGroupableRoutes.add(routeId); public Builder addDeselectableRoute(@NonNull String routeId) { mDeselectableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a groupable route * Removes a route from the deselectable routes. */ @NonNull public Builder removeGroupableRoute(String routeId) { mGroupableRoutes.remove(routeId); public Builder removeDeselectableRoute(@NonNull String routeId) { mDeselectableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Adds a transferrable route * Clears the groupable routes. */ @NonNull public Builder addTransferrableRoute(String routeId) { mTransferrableRoutes.add(routeId); public Builder clearGroupableRoutes() { mGroupableRoutes.clear(); return this; } /** * Removes a transferrable route * Adds a route to the groupable routes. */ @NonNull public Builder removeTransferrableRoute(String routeId) { mTransferrableRoutes.remove(routeId); public Builder addGroupableRoute(@NonNull String routeId) { mGroupableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Builds a route session info * Removes a route from the groupable routes. */ @NonNull public Builder removeGroupableRoute(@NonNull String routeId) { mGroupableRoutes.remove(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Clears the transferrable routes. */ @NonNull public Builder clearTransferrableRoutes() { mTransferrableRoutes.clear(); return this; } /** * Adds a route to the transferrable routes. */ @NonNull public Builder addTransferrableRoute(@NonNull String routeId) { mTransferrableRoutes.add(Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Removes a route from the transferrable routes. */ @NonNull public Builder removeTransferrableRoute(@NonNull String routeId) { mTransferrableRoutes.remove( Objects.requireNonNull(routeId, "routeId must not be null")); return this; } /** * Builds a route session info. */ @NonNull public RouteSessionInfo build() { Loading
media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java +47 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.Intent; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2ProviderService; import android.media.RouteSessionInfo; import android.os.Bundle; import android.os.IBinder; Loading Loading @@ -159,10 +160,55 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService publishRoutes(); } @Override public void onCreateSession(String packageName, String routeId, String controlCategory, int sessionId) { RouteSessionInfo sessionInfo = new RouteSessionInfo.Builder( sessionId, packageName, controlCategory) .addSelectedRoute(routeId) .build(); notifySessionCreated(sessionId, sessionInfo, null); } @Override public void onDestroySession(int sessionId, RouteSessionInfo lastSessionInfo) {} @Override public void onAddRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); //TODO: we may want to remove route if it belongs to another session RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .addSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } @Override public void onRemoveRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .removeSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } @Override public void onTransferRoute(int sessionId, String routeId) { RouteSessionInfo sessionInfo = getSessionInfo(sessionId); RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo) .clearSelectedRoutes() .addSelectedRoute(routeId) .build(); setSessionInfo(sessionId, newSessionInfo); publishRoutes(); } void publishRoutes() { MediaRoute2ProviderInfo info = new MediaRoute2ProviderInfo.Builder() .addRoutes(mRoutes.values()) .build(); setProviderInfo(info); updateProviderInfo(info); } }