blob: 320659660eaa08187f2141a45e208e57f971ba8f [file] [log] [blame]
/*
* Copyright 2018 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 com.android.support.mediarouter.media;
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.util.TimeUtils;
/**
* Describes the playback status of a media session.
* <p>
* This class is part of the remote playback protocol described by the
* {@link MediaControlIntent MediaControlIntent} class.
* </p><p>
* When a media session is created, it is initially in the
* {@link #SESSION_STATE_ACTIVE active} state. When the media session ends
* normally, it transitions to the {@link #SESSION_STATE_ENDED ended} state.
* If the media session is invalidated due to another session forcibly taking
* control of the route, then it transitions to the
* {@link #SESSION_STATE_INVALIDATED invalidated} state.
* Refer to the documentation of each state for an explanation of its meaning.
* </p><p>
* To monitor session status, the application should supply a {@link PendingIntent} to use as the
* {@link MediaControlIntent#EXTRA_SESSION_STATUS_UPDATE_RECEIVER session status update receiver}
* for a given {@link MediaControlIntent#ACTION_START_SESSION session start request}.
* </p><p>
* This object is immutable once created using a {@link Builder} instance.
* </p>
*/
public final class MediaSessionStatus {
static final String KEY_TIMESTAMP = "timestamp";
static final String KEY_SESSION_STATE = "sessionState";
static final String KEY_QUEUE_PAUSED = "queuePaused";
static final String KEY_EXTRAS = "extras";
final Bundle mBundle;
/**
* Session state: Active.
* <p>
* Indicates that the media session is active and in control of the route.
* </p>
*/
public static final int SESSION_STATE_ACTIVE = 0;
/**
* Session state: Ended.
* <p>
* Indicates that the media session was ended normally using the
* {@link MediaControlIntent#ACTION_END_SESSION end session} action.
* </p><p>
* A terminated media session cannot be used anymore. To play more media, the
* application must start a new session.
* </p>
*/
public static final int SESSION_STATE_ENDED = 1;
/**
* Session state: Invalidated.
* <p>
* Indicates that the media session was invalidated involuntarily due to
* another session taking control of the route.
* </p><p>
* An invalidated media session cannot be used anymore. To play more media, the
* application must start a new session.
* </p>
*/
public static final int SESSION_STATE_INVALIDATED = 2;
MediaSessionStatus(Bundle bundle) {
mBundle = bundle;
}
/**
* Gets the timestamp associated with the status information in
* milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
*
* @return The status timestamp in the {@link SystemClock#elapsedRealtime()} time base.
*/
public long getTimestamp() {
return mBundle.getLong(KEY_TIMESTAMP);
}
/**
* Gets the session state.
*
* @return The session state. One of {@link #SESSION_STATE_ACTIVE},
* {@link #SESSION_STATE_ENDED}, or {@link #SESSION_STATE_INVALIDATED}.
*/
public int getSessionState() {
return mBundle.getInt(KEY_SESSION_STATE, SESSION_STATE_INVALIDATED);
}
/**
* Returns true if the session's queue is paused.
*
* @return True if the session's queue is paused.
*/
public boolean isQueuePaused() {
return mBundle.getBoolean(KEY_QUEUE_PAUSED);
}
/**
* Gets a bundle of extras for this status object.
* The extras will be ignored by the media router but they may be used
* by applications.
*/
public Bundle getExtras() {
return mBundle.getBundle(KEY_EXTRAS);
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append("MediaSessionStatus{ ");
result.append("timestamp=");
TimeUtils.formatDuration(SystemClock.elapsedRealtime() - getTimestamp(), result);
result.append(" ms ago");
result.append(", sessionState=").append(sessionStateToString(getSessionState()));
result.append(", queuePaused=").append(isQueuePaused());
result.append(", extras=").append(getExtras());
result.append(" }");
return result.toString();
}
private static String sessionStateToString(int sessionState) {
switch (sessionState) {
case SESSION_STATE_ACTIVE:
return "active";
case SESSION_STATE_ENDED:
return "ended";
case SESSION_STATE_INVALIDATED:
return "invalidated";
}
return Integer.toString(sessionState);
}
/**
* Converts this object to a bundle for serialization.
*
* @return The contents of the object represented as a bundle.
*/
public Bundle asBundle() {
return mBundle;
}
/**
* Creates an instance from a bundle.
*
* @param bundle The bundle, or null if none.
* @return The new instance, or null if the bundle was null.
*/
public static MediaSessionStatus fromBundle(Bundle bundle) {
return bundle != null ? new MediaSessionStatus(bundle) : null;
}
/**
* Builder for {@link MediaSessionStatus media session status objects}.
*/
public static final class Builder {
private final Bundle mBundle;
/**
* Creates a media session status builder using the current time as the
* reference timestamp.
*
* @param sessionState The session state.
*/
public Builder(int sessionState) {
mBundle = new Bundle();
setTimestamp(SystemClock.elapsedRealtime());
setSessionState(sessionState);
}
/**
* Creates a media session status builder whose initial contents are
* copied from an existing status.
*/
public Builder(MediaSessionStatus status) {
if (status == null) {
throw new IllegalArgumentException("status must not be null");
}
mBundle = new Bundle(status.mBundle);
}
/**
* Sets the timestamp associated with the status information in
* milliseconds since boot in the {@link SystemClock#elapsedRealtime} time base.
*/
public Builder setTimestamp(long elapsedRealtimeTimestamp) {
mBundle.putLong(KEY_TIMESTAMP, elapsedRealtimeTimestamp);
return this;
}
/**
* Sets the session state.
*/
public Builder setSessionState(int sessionState) {
mBundle.putInt(KEY_SESSION_STATE, sessionState);
return this;
}
/**
* Sets whether the queue is paused.
*/
public Builder setQueuePaused(boolean queuePaused) {
mBundle.putBoolean(KEY_QUEUE_PAUSED, queuePaused);
return this;
}
/**
* Sets a bundle of extras for this status object.
* The extras will be ignored by the media router but they may be used
* by applications.
*/
public Builder setExtras(Bundle extras) {
mBundle.putBundle(KEY_EXTRAS, extras);
return this;
}
/**
* Builds the {@link MediaSessionStatus media session status object}.
*/
public MediaSessionStatus build() {
return new MediaSessionStatus(mBundle);
}
}
}