Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7012db74 authored by Dongwon Kang's avatar Dongwon Kang Committed by Android (Google) Code Review
Browse files

Merge "TIF: Address the feedback from the API review - 2/3" into lmp-preview-dev

parents 2750d21d b8a64416
Loading
Loading
Loading
Loading
+10 −15
Original line number Diff line number Diff line
@@ -15933,23 +15933,10 @@ package android.media.tv {
  }
  public final class TvInputManager {
    method public void createSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
    method public boolean getAvailability(java.lang.String);
    method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
  }
  public static final class TvInputManager.Session {
    method public void release();
    method public void setStreamVolume(float);
    method public void tune(android.net.Uri);
  }
  public static abstract class TvInputManager.SessionCallback {
    ctor public TvInputManager.SessionCallback();
    method public void onSessionCreated(android.media.tv.TvInputManager.Session);
    method public void onSessionReleased(android.media.tv.TvInputManager.Session);
  }
  public static abstract class TvInputManager.TvInputListener {
    ctor public TvInputManager.TvInputListener();
    method public void onAvailabilityChanged(java.lang.String, boolean);
@@ -15984,18 +15971,26 @@ package android.media.tv {
    ctor public TvView(android.content.Context);
    ctor public TvView(android.content.Context, android.util.AttributeSet);
    ctor public TvView(android.content.Context, android.util.AttributeSet, int);
    method public void bindTvInput(java.lang.String, android.media.tv.TvInputManager.SessionCallback);
    method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
    method public boolean onUnhandledInputEvent(android.view.InputEvent);
    method public void reset();
    method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
    method public void setStreamVolume(float);
    method public void unbindTvInput();
    method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
    method public void tune(java.lang.String, android.net.Uri);
    field public static final int ERROR_BUSY = 0; // 0x0
    field public static final int ERROR_TV_INPUT_DISCONNECTED = 1; // 0x1
  }
  public static abstract interface TvView.OnUnhandledInputEventListener {
    method public abstract boolean onUnhandledInputEvent(android.view.InputEvent);
  }
  public static abstract class TvView.TvInputListener {
    ctor public TvView.TvInputListener();
    method public void onError(java.lang.String, int);
  }
}
package android.mtp {
+6 −1
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ public final class TvInputManager {

    /**
     * Interface used to receive the created session.
     * @hide
     */
    public abstract static class SessionCallback {
        /**
@@ -467,6 +468,7 @@ public final class TvInputManager {
     * @param callback a callback used to receive the created session.
     * @param handler a {@link Handler} that the session creation will be delivered to.
     * @throws IllegalArgumentException if any of the arguments is {@code null}.
     * @hide
     */
    public void createSession(String inputId, final SessionCallback callback,
            Handler handler) {
@@ -491,7 +493,10 @@ public final class TvInputManager {
        }
    }

    /** The Session provides the per-session functionality of TV inputs. */
    /**
     * The Session provides the per-session functionality of TV inputs.
     * @hide
     */
    public static final class Session {
        static final int DISPATCH_IN_PROGRESS = -1;
        static final int DISPATCH_NOT_HANDLED = 0;
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ public abstract class TvInputService extends Service {
    public abstract Session onCreateSession();

    /**
     * Base class for derived classes to implement to provide {@link TvInputManager.Session}.
     * Base class for derived classes to implement to provide a TV input session.
     */
    public abstract class Session implements KeyEvent.Callback {
        private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
+152 −54
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.graphics.Rect;
import android.media.tv.TvInputManager.Session;
import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
import android.media.tv.TvInputManager.SessionCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
@@ -38,9 +39,21 @@ import android.view.ViewRootImpl;
 * View playing TV
 */
public class TvView extends SurfaceView {
    private static final String TAG = "TvView";
    // STOPSHIP: Turn debugging off.
    private static final boolean DEBUG = true;
    private static final String TAG = "TvView";

    /**
     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the requested TV
     * input is busy and unable to handle the request.
     */
    public static final int ERROR_BUSY = 0;

    /**
     * Passed with {@link TvInputListener#onError(String, int)}. Indicates that the underlying TV
     * input has been disconnected.
     */
    public static final int ERROR_TV_INPUT_DISCONNECTED = 1;

    private final Handler mHandler = new Handler();
    private TvInputManager.Session mSession;
@@ -48,7 +61,8 @@ public class TvView extends SurfaceView {
    private boolean mOverlayViewCreated;
    private Rect mOverlayViewFrame;
    private final TvInputManager mTvInputManager;
    private SessionCallback mSessionCallback;
    private MySessionCallback mSessionCallback;
    private TvInputListener mListener;
    private OnUnhandledInputEventListener mOnUnhandledInputEventListener;

    private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@@ -113,57 +127,70 @@ public class TvView extends SurfaceView {
    }

    /**
     * Binds a TV input to this view. {@link SessionCallback#onSessionCreated} will be
     * called to send the result of this binding with {@link TvInputManager.Session}.
     * If a TV input is already bound, the input will be unbound from this view and its session
     * will be released.
     * Sets a listener for events in this TvView.
     *
     * @param listener The listener to be called with events. A value of {@code null} removes any
     *         existing listener.
     */
    public void setTvInputListener(TvInputListener listener) {
        mListener = listener;
    }

    /**
     * Sets the relative stream volume of this session to handle a change of audio focus.
     *
     * @param volume A volume value between 0.0f to 1.0f.
     */
    public void setStreamVolume(float volume) {
        if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
        if (mSession == null) {
            return;
        }
        mSession.setStreamVolume(volume);
    }

    /**
     * Tunes to a given channel.
     *
     * @param inputId the id of TV input which will be bound to this view.
     * @param callback called when TV input is bound. The callback sends
     *        {@link TvInputManager.Session}
     * @throws IllegalArgumentException if any of the arguments is {@code null}.
     * @param inputId the id of TV input which will play the given channel.
     * @param channelUri The URI of a channel.
     */
    public void bindTvInput(String inputId, SessionCallback callback) {
    public void tune(String inputId, Uri channelUri) {
        if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
        if (TextUtils.isEmpty(inputId)) {
            throw new IllegalArgumentException("inputId cannot be null or an empty string");
        }
        if (callback == null) {
            throw new IllegalArgumentException("callback cannot be null");
        if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) {
            if (mSession != null) {
                mSession.tune(channelUri);
            } else {
                // Session is not created yet. Replace the channel which will be set once the
                // session is made.
                mSessionCallback.mChannelUri = channelUri;
            }
        } else {
            if (mSession != null) {
                release();
            }
        // When bindTvInput is called multiple times before the callback is called,
        // only the callback of the last bindTvInput call will be actually called back.
            // When createSession() is called multiple times before the callback is called,
            // only the callback of the last createSession() call will be actually called back.
            // The previous callbacks will be ignored. For the logic, mSessionCallback
        // is newly assigned for every bindTvInput call and compared with
            // is newly assigned for every createSession request and compared with
            // MySessionCreateCallback.this.
        mSessionCallback = new MySessionCallback(callback);
            mSessionCallback = new MySessionCallback(inputId, channelUri);
            mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
        }
    }

    /**
     * Unbinds a TV input currently bound. Its corresponding {@link TvInputManager.Session}
     * is released.
     * Resets this TvView.
     * <p>
     * This method is primarily used to un-tune the current TvView.
     */
    public void unbindTvInput() {
    public void reset() {
        if (mSession != null) {
            release();
        }
        mSessionCallback = null;
    }

    /**
     * Sets the relative stream volume of this session to handle a change of audio focus.
     *
     * @param volume A volume value between 0.0f to 1.0f.
     */
    public void setStreamVolume(float volume) {
        if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
        if (mSession == null) {
            return;
        }
        mSession.setStreamVolume(volume);
    }

    /**
@@ -290,6 +317,7 @@ public class TvView extends SurfaceView {
        removeSessionOverlayView();
        mSession.release();
        mSession = null;
        mSessionCallback = null;
    }

    private void setSessionSurface(Surface surface) {
@@ -338,6 +366,71 @@ public class TvView extends SurfaceView {
                location[0] + getWidth(), location[1] + getHeight());
    }

    /**
     * Interface used to receive various status updates on the {@link TvView}.
     */
    public abstract static class TvInputListener {

        /**
         * This is invoked when an error occurred while handling requested operation.
         *
         * @param inputId The ID of the TV input bound to this view.
         * @param errorCode The error code. For the details of error code, please see
         *         {@link TvView}.
         */
        public void onError(String inputId, int errorCode) {
        }

        /**
         * This is invoked when the view is tuned to a specific channel and starts decoding video
         * stream from there. It is also called later when the video format is changed.
         *
         * @param inputId The ID of the TV input bound to this view.
         * @param width The width of the video.
         * @param height The height of the video.
         * @param interlaced {@code true} if the video is interlaced, {@code false} if the video is
         *            progressive.
         * @hide
         */
        public void onVideoStreamChanged(String inputId, int width, int height,
                boolean interlaced) {
        }

        /**
         * This is invoked when the view is tuned to a specific channel and starts decoding audio
         * stream from there. It is also called later when the audio format is changed.
         *
         * @param inputId The ID of the TV input bound to this view.
         * @param channelCount The number of channels in the audio stream.
         * @hide
         */
        public void onAudioStreamChanged(String inputId, int channelCount) {
        }

        /**
         * This is invoked when the view is tuned to a specific channel and starts decoding data
         * stream that includes subtitle information from the channel. It is also called later when
         * the information disappears or appears.
         *
         * @param inputId The ID of the TV input bound to this view.
         * @param hasClosedCaption {@code true} if the stream contains closed caption, {@code false}
         *            otherwise.
         * @hide
         */
        public void onClosedCaptionStreamChanged(String inputId, boolean hasClosedCaption) {
        }

        /**
         * This is invoked when a custom event from the bound TV input is sent to this view.
         *
         * @param eventType The type of the event.
         * @param eventArgs Optional arguments of the event.
         * @hide
         */
        public void onEvent(String inputId, String eventType, Bundle eventArgs) {
        }
    }

    /**
     * Interface definition for a callback to be invoked when the unhandled input event is received.
     */
@@ -356,10 +449,12 @@ public class TvView extends SurfaceView {
    }

    private class MySessionCallback extends SessionCallback {
        final SessionCallback mExternalCallback;
        final String mInputId;
        Uri mChannelUri;

        MySessionCallback(SessionCallback externalCallback) {
            mExternalCallback = externalCallback;
        MySessionCallback(String inputId, Uri channelUri) {
            mInputId = inputId;
            mChannelUri = channelUri;
        }

        @Override
@@ -380,17 +475,20 @@ public class TvView extends SurfaceView {
                    setSessionSurface(mSurface);
                }
                createSessionOverlayView();
                mSession.tune(mChannelUri);
            } else {
                if (mListener != null) {
                    mListener.onError(mInputId, ERROR_BUSY);
                }
            if (mExternalCallback != null) {
                mExternalCallback.onSessionCreated(session);
            }
        }

        @Override
        public void onSessionReleased(Session session) {
            mSession = null;
            if (mExternalCallback != null) {
                mExternalCallback.onSessionReleased(session);
            mSessionCallback = null;
            if (mListener != null) {
                mListener.onError(mInputId, ERROR_TV_INPUT_DISCONNECTED);
            }
        }

@@ -400,8 +498,8 @@ public class TvView extends SurfaceView {
            if (DEBUG) {
                Log.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
            }
            if (mExternalCallback != null) {
                mExternalCallback.onVideoStreamChanged(session, width, height, interlaced);
            if (mListener != null) {
                mListener.onVideoStreamChanged(mInputId, width, height, interlaced);
            }
        }

@@ -410,8 +508,8 @@ public class TvView extends SurfaceView {
            if (DEBUG) {
                Log.d(TAG, "onAudioStreamChanged(" + channelCount + ")");
            }
            if (mExternalCallback != null) {
                mExternalCallback.onAudioStreamChanged(session, channelCount);
            if (mListener != null) {
                mListener.onAudioStreamChanged(mInputId, channelCount);
            }
        }

@@ -420,16 +518,16 @@ public class TvView extends SurfaceView {
            if (DEBUG) {
                Log.d(TAG, "onClosedCaptionStreamChanged(" + hasClosedCaption + ")");
            }
            if (mExternalCallback != null) {
                mExternalCallback.onClosedCaptionStreamChanged(session, hasClosedCaption);
            if (mListener != null) {
                mListener.onClosedCaptionStreamChanged(mInputId, hasClosedCaption);
            }
        }

        @Override
        public void onSessionEvent(TvInputManager.Session session, String eventType,
                Bundle eventArgs) {
            if (mExternalCallback != null) {
                mExternalCallback.onSessionEvent(session, eventType, eventArgs);
            if (mListener != null) {
                mListener.onEvent(mInputId, eventType, eventArgs);
            }
        }
    }