diff options
| author | 2019-12-18 05:31:53 +0000 | |
|---|---|---|
| committer | 2019-12-18 05:31:53 +0000 | |
| commit | 0d648ab28efd213570cba44d774f1946a08ee424 (patch) | |
| tree | 9cc81b9e636214a608a7eb4668dd31a36e6eff97 | |
| parent | b4bb59a9f464a3b8b034061bd0b6eaa9dadcbd6c (diff) | |
| parent | cc26ad66758315b882481cfcf65c7b8eaec73f1b (diff) | |
Merge "MediaRouter2: Add RouteSessionController"
| -rw-r--r-- | media/java/android/media/RouteSessionController.java | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/media/java/android/media/RouteSessionController.java b/media/java/android/media/RouteSessionController.java new file mode 100644 index 000000000000..5ff721837573 --- /dev/null +++ b/media/java/android/media/RouteSessionController.java @@ -0,0 +1,208 @@ +/* + * Copyright 2019 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 com.android.internal.annotations.GuardedBy; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + +/** + * A class to control media route session in media route provider. + * For example, adding/removing/transferring routes to session can be done through this class. + * Instances are created by {@link MediaRouter2}. + * + * TODO: When session is introduced, change Javadoc of all methods/classes by using [@link Session]. + * + * @hide + */ +public class RouteSessionController { + private final int mSessionId; + private final String mCategory; + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private final CopyOnWriteArrayList<CallbackRecord> mCallbackRecords = + new CopyOnWriteArrayList<>(); + + private volatile boolean mIsReleased; + + /** + * @param sessionId the ID of the session. + * @param category The category of media routes that the session includes. + */ + RouteSessionController(int sessionId, @NonNull String category) { + mSessionId = sessionId; + mCategory = category; + } + + /** + * @return the ID of this controller + */ + public int getSessionId() { + return mSessionId; + } + + /** + * @return the category of routes that the session includes. + */ + @NonNull + public String getCategory() { + return mCategory; + } + + /** + * @return the list of currently connected routes + */ + @NonNull + public List<MediaRoute2Info> getRoutes() { + // TODO: Implement this when SessionInfo is introduced. + return null; + } + + /** + * Returns true if the session is released, false otherwise. + * If it is released, then all other getters from this instance may return invalid values. + * Also, any operations to this instance will be ignored once released. + * + * @see #release + * @see Callback#onReleased + */ + public boolean isReleased() { + return mIsReleased; + } + + /** + * Add routes to the remote session. + * + * @see #getRoutes() + * @see Callback#onSessionInfoChanged + */ + public void addRoutes(List<MediaRoute2Info> routes) { + // TODO: Implement this when the actual connection logic is implemented. + } + + /** + * Remove routes from this session. Media may be stopped on those devices. + * Route removal requests that are not currently in {@link #getRoutes()} will be ignored. + * + * @see #getRoutes() + * @see Callback#onSessionInfoChanged + */ + public void removeRoutes(List<MediaRoute2Info> routes) { + // TODO: Implement this when the actual connection logic is implemented. + } + + /** + * Registers a {@link Callback} for monitoring route changes. + * If the same callback is registered previously, previous executor will be overwritten with the + * new one. + */ + public void registerCallback(Executor executor, Callback callback) { + if (mIsReleased) { + return; + } + Objects.requireNonNull(executor, "executor must not be null"); + Objects.requireNonNull(callback, "callback must not be null"); + + synchronized (mLock) { + CallbackRecord recordWithSameCallback = null; + for (CallbackRecord record : mCallbackRecords) { + if (callback == record.mCallback) { + recordWithSameCallback = record; + break; + } + } + + if (recordWithSameCallback != null) { + recordWithSameCallback.mExecutor = executor; + } else { + mCallbackRecords.add(new CallbackRecord(executor, callback)); + } + } + } + + /** + * Unregisters a previously registered {@link Callback}. + */ + public void unregisterCallback(Callback callback) { + Objects.requireNonNull(callback, "callback must not be null"); + + synchronized (mLock) { + CallbackRecord recordToRemove = null; + for (CallbackRecord record : mCallbackRecords) { + if (callback == record.mCallback) { + recordToRemove = record; + break; + } + } + + if (recordToRemove != null) { + mCallbackRecords.remove(recordToRemove); + } + } + } + + /** + * Release this session. + * Any operation on this session after calling this method will be ignored. + * + * @param stopMedia Should the device where the media is played + * be stopped after this session is released. + */ + public void release(boolean stopMedia) { + mIsReleased = true; + mCallbackRecords.clear(); + // TODO: Use stopMedia variable when the actual connection logic is implemented. + } + + /** + * Callback class for getting updates on routes and session release. + */ + public static class Callback { + + /** + * Called when the session info has changed. + * TODO: When SessionInfo is introduced, uncomment below argument. + */ + void onSessionInfoChanged(/* SessionInfo info */) {} + + /** + * Called when the session is released. Session can be released by the controller using + * {@link #release(boolean)}, or by the {@link MediaRoute2ProviderService} itself. + * One can do clean-ups here. + * + * TODO: When SessionInfo is introduced, change the javadoc of releasing session on + * provider side. + */ + void onReleased(int reason, boolean shouldStop) {} + } + + private class CallbackRecord { + public final Callback mCallback; + public Executor mExecutor; + + CallbackRecord(@NonNull Executor executor, @NonNull Callback callback) { + mExecutor = executor; + mCallback = callback; + } + } +} |