| /* |
| * 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 androidx.media2.session; |
| |
| import static androidx.annotation.RestrictTo.Scope.LIBRARY; |
| |
| import android.os.Bundle; |
| import android.os.SystemClock; |
| import android.support.v4.media.session.MediaControllerCompat; |
| import android.support.v4.media.session.MediaSessionCompat; |
| |
| import androidx.annotation.IntDef; |
| import androidx.annotation.Nullable; |
| import androidx.annotation.RestrictTo; |
| import androidx.concurrent.futures.ResolvableFuture; |
| import androidx.media2.common.MediaItem; |
| import androidx.media2.common.SessionPlayer; |
| import androidx.versionedparcelable.CustomVersionedParcelable; |
| import androidx.versionedparcelable.NonParcelField; |
| import androidx.versionedparcelable.ParcelField; |
| import androidx.versionedparcelable.VersionedParcelize; |
| |
| import com.google.common.util.concurrent.ListenableFuture; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * Result class to be used with {@link ListenableFuture} for asynchronous calls between {@link |
| * MediaSession} and {@link MediaController}. |
| * |
| * @deprecated androidx.media2 is deprecated. Please migrate to <a |
| * href="https://developer.android.com/guide/topics/media/media3">androidx.media3</a>. |
| */ |
| @Deprecated |
| @VersionedParcelize(isCustom = true) |
| public class SessionResult extends CustomVersionedParcelable implements RemoteResult { |
| /** |
| * Result code representing that the command is successfully completed. |
| * <p> |
| * Interoperability: This code is also used to tell that the command was successfully sent, but |
| * the result is unknown when connected with {@link MediaSessionCompat} or |
| * {@link MediaControllerCompat}. |
| */ |
| // Redefined to override the Javadoc |
| public static final int RESULT_SUCCESS = 0; |
| |
| /** |
| */ |
| @IntDef(flag = false, /*prefix = "RESULT_CODE",*/ value = { |
| RESULT_SUCCESS, |
| RESULT_ERROR_UNKNOWN, |
| RESULT_ERROR_INVALID_STATE, |
| RESULT_ERROR_BAD_VALUE, |
| RESULT_ERROR_PERMISSION_DENIED, |
| RESULT_ERROR_IO, |
| RESULT_INFO_SKIPPED, |
| RESULT_ERROR_SESSION_DISCONNECTED, |
| RESULT_ERROR_NOT_SUPPORTED, |
| RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED, |
| RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED, |
| RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT, |
| RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED, |
| RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION, |
| RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED, |
| RESULT_ERROR_SESSION_SETUP_REQUIRED}) |
| @Retention(RetentionPolicy.SOURCE) |
| @RestrictTo(LIBRARY) |
| public @interface ResultCode {} |
| |
| @ParcelField(1) |
| int mResultCode; |
| @ParcelField(2) |
| long mCompletionTime; |
| @ParcelField(3) |
| Bundle mCustomCommandResult; |
| // Parceled via mParcelableItem. |
| @NonParcelField |
| MediaItem mItem; |
| // For parceling mItem. Should be only used by onPreParceling() and onPostParceling(). |
| @ParcelField(4) |
| MediaItem mParcelableItem; |
| |
| // WARNING: Adding a new ParcelField may break old library users (b/152830728) |
| |
| /** |
| * Constructor to be used by {@link MediaSession.SessionCallback#onCustomCommand( |
| * MediaSession, MediaSession.ControllerInfo, SessionCommand, Bundle)}. |
| * |
| * @param resultCode result code |
| * @param customCommandResult custom command result. |
| */ |
| public SessionResult(@ResultCode int resultCode, @Nullable Bundle customCommandResult) { |
| this(resultCode, customCommandResult, null, SystemClock.elapsedRealtime()); |
| } |
| |
| // For versioned-parcelable |
| SessionResult() { |
| // no-op |
| } |
| |
| SessionResult(@ResultCode int resultCode) { |
| this(resultCode, null); |
| } |
| |
| SessionResult(@ResultCode int resultCode, Bundle customCommandResult, MediaItem item) { |
| this(resultCode, customCommandResult, item, SystemClock.elapsedRealtime()); |
| } |
| |
| SessionResult(@ResultCode int resultCode, @Nullable Bundle customCommandResult, |
| @Nullable MediaItem item, long completionTime) { |
| mResultCode = resultCode; |
| mCustomCommandResult = customCommandResult; |
| mItem = item; |
| mCompletionTime = completionTime; |
| } |
| |
| @Nullable |
| static SessionResult from(@Nullable SessionPlayer.PlayerResult result) { |
| if (result == null) { |
| return null; |
| } |
| return new SessionResult(result.getResultCode(), null, result.getMediaItem(), |
| result.getCompletionTime()); |
| } |
| |
| static ListenableFuture<SessionResult> createFutureWithResult(@ResultCode int resultCode) { |
| ResolvableFuture<SessionResult> result = ResolvableFuture.create(); |
| result.set(new SessionResult(resultCode)); |
| return result; |
| } |
| |
| /** |
| * Gets the result code. |
| * |
| * @return result code |
| * @see #RESULT_SUCCESS |
| * @see #RESULT_ERROR_UNKNOWN |
| * @see #RESULT_ERROR_INVALID_STATE |
| * @see #RESULT_ERROR_BAD_VALUE |
| * @see #RESULT_ERROR_PERMISSION_DENIED |
| * @see #RESULT_ERROR_IO |
| * @see #RESULT_INFO_SKIPPED |
| * @see #RESULT_ERROR_SESSION_DISCONNECTED |
| * @see #RESULT_ERROR_NOT_SUPPORTED |
| * @see #RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED |
| * @see #RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED |
| * @see #RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT |
| * @see #RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED |
| * @see #RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION |
| * @see #RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED |
| * @see #RESULT_ERROR_SESSION_SETUP_REQUIRED |
| */ |
| @Override |
| @ResultCode |
| public int getResultCode() { |
| return mResultCode; |
| } |
| |
| /** |
| * Gets the result of |
| * {@link MediaSession#sendCustomCommand(MediaSession.ControllerInfo, SessionCommand, Bundle)} |
| * and {@link MediaController#sendCustomCommand(SessionCommand, Bundle)} only when this object |
| * is returned by one of them. |
| * <p> |
| * If this object is returned by other methods, this method will be {@code null}. |
| * |
| * @see MediaSession#sendCustomCommand(MediaSession.ControllerInfo, SessionCommand, Bundle) |
| * @see MediaController#sendCustomCommand(SessionCommand, Bundle) |
| * @return result of sending custom command |
| */ |
| @Nullable |
| public Bundle getCustomCommandResult() { |
| return mCustomCommandResult; |
| } |
| |
| /** |
| * Gets the completion time of the command. Being more specific, it's the same as |
| * {@link SystemClock#elapsedRealtime()} when the command completed. |
| * |
| * @return completion time of the command |
| */ |
| @Override |
| public long getCompletionTime() { |
| return mCompletionTime; |
| } |
| |
| /** |
| * Gets the {@link MediaItem} for which the command was executed. In other words, this is |
| * the current media item when the command completed. |
| * <p> |
| * Can be {@code null} for many reasons. For examples, |
| * <ul> |
| * <li>Error happened. |
| * <li>Current media item was {@code null} at that time. |
| * <li>Command is irrelevant with the media item (e.g. custom command). |
| * </ul> |
| * |
| * @return media item when the command completed. Can be {@code null} for an error, the |
| * current media item was {@code null}, or any other reason. |
| */ |
| @Override |
| @Nullable |
| public MediaItem getMediaItem() { |
| return mItem; |
| } |
| |
| /** |
| */ |
| @RestrictTo(LIBRARY) |
| @Override |
| @SuppressWarnings("SynchronizeOnNonFinalField") // mItem is effectively final. |
| public void onPreParceling(boolean isStream) { |
| if (mItem != null) { |
| synchronized (mItem) { |
| if (mParcelableItem == null) { |
| mParcelableItem = MediaUtils.upcastForPreparceling(mItem); |
| } |
| } |
| } |
| } |
| |
| /** |
| */ |
| @RestrictTo(LIBRARY) |
| @Override |
| public void onPostParceling() { |
| mItem = mParcelableItem; |
| } |
| } |