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

Commit f8c88832 authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge "[TIAF] Fixed TIAS can not receive key event"

parents 5f2a1a71 730e843f
Loading
Loading
Loading
Loading
+94 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
import android.media.tv.interactive.TvIAppManager.Session;
import android.media.tv.interactive.TvIAppManager.Session.FinishedInputEventCallback;
import android.media.tv.interactive.TvIAppManager.SessionCallback;
import android.net.Uri;
import android.os.Bundle;
@@ -34,11 +35,14 @@ import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;

import java.util.List;

@@ -80,6 +84,7 @@ public class TvIAppView extends ViewGroup {
    private final AttributeSet mAttrs;
    private final int mDefStyleAttr;
    private final XmlResourceParser mParser;
    private OnUnhandledInputEventListener mOnUnhandledInputEventListener;

    private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
        @Override
@@ -272,6 +277,77 @@ public class TvIAppView extends ViewGroup {
        mSession.dispatchSurfaceChanged(format, width, height);
    }

    private final FinishedInputEventCallback mFinishedInputEventCallback =
            new FinishedInputEventCallback() {
                @Override
                public void onFinishedInputEvent(Object token, boolean handled) {
                    if (DEBUG) {
                        Log.d(TAG, "onFinishedInputEvent(token=" + token + ", handled="
                                + handled + ")");
                    }
                    if (handled) {
                        return;
                    }
                    // TODO: Re-order unhandled events.
                    InputEvent event = (InputEvent) token;
                    if (dispatchUnhandledInputEvent(event)) {
                        return;
                    }
                    ViewRootImpl viewRootImpl = getViewRootImpl();
                    if (viewRootImpl != null) {
                        viewRootImpl.dispatchUnhandledInputEvent(event);
                    }
                }
            };

    /**
     * Dispatches an unhandled input event to the next receiver.
     */
    public boolean dispatchUnhandledInputEvent(@NonNull InputEvent event) {
        if (mOnUnhandledInputEventListener != null) {
            if (mOnUnhandledInputEventListener.onUnhandledInputEvent(event)) {
                return true;
            }
        }
        return onUnhandledInputEvent(event);
    }

    /**
     * Called when an unhandled input event also has not been handled by the user provided
     * callback. This is the last chance to handle the unhandled input event in the TvIAppView.
     *
     * @param event The input event.
     * @return If you handled the event, return {@code true}. If you want to allow the event to be
     *         handled by the next receiver, return {@code false}.
     */
    public boolean onUnhandledInputEvent(@NonNull InputEvent event) {
        return false;
    }

    /**
     * Registers a callback to be invoked when an input event is not handled
     * by the TV Interactive App.
     *
     * @param listener The callback to be invoked when the unhandled input event is received.
     */
    public void setOnUnhandledInputEventListener(@NonNull OnUnhandledInputEventListener listener) {
        mOnUnhandledInputEventListener = listener;
    }

    @Override
    public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
        if (super.dispatchKeyEvent(event)) {
            return true;
        }
        if (mSession == null) {
            return false;
        }
        InputEvent copiedEvent = event.copy();
        int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
                mHandler);
        return ret != Session.DISPATCH_NOT_HANDLED;
    }

    /**
     * Prepares the interactive application.
     */
@@ -514,6 +590,24 @@ public class TvIAppView extends ViewGroup {
         */
        public void onRequestTrackInfoList(@NonNull String iAppServiceId) {
        }

    }

    /**
     * Interface definition for a callback to be invoked when the unhandled input event is received.
     */
    public interface OnUnhandledInputEventListener {
        /**
         * Called when an input event was not handled by the TV Interactive App.
         *
         * <p>This is called asynchronously from where the event is dispatched. It gives the host
         * application a chance to handle the unhandled input events.
         *
         * @param event The input event.
         * @return If you handled the event, return {@code true}. If you want to allow the event to
         *         be handled by the next receiver, return {@code false}.
         */
        boolean onUnhandledInputEvent(@NonNull InputEvent event);
    }

    private class MySessionCallback extends SessionCallback {