11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccipackage org.chromium.chromecast.shell;
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport android.content.Context;
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport android.graphics.Color;
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport android.util.AttributeSet;
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport android.view.LayoutInflater;
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport android.widget.FrameLayout;
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.base.CalledByNative;
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.base.JNINamespace;
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.content.browser.ContentViewCore;
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.content.browser.ContentViewRenderView;
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.ui.base.WindowAndroid;
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/**
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Container and generator of CastWindow instances.
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci@JNINamespace("chromecast::shell")
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccipublic class CastWindowManager extends FrameLayout {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private static final String TAG = "CastWindowManager";
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private WindowAndroid mWindow;
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private CastWindowAndroid mActiveCastWindow;
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The target for all content rendering.
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private ContentViewRenderView mContentViewRenderView;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Delegate to deliver events from the native window.
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public interface Delegate {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        public void onCreated();
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        public void onClosed();
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private Delegate mDelegate;
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Constructor for inflating via XML.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public CastWindowManager(Context context, AttributeSet attrs) {
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        super(context, attrs);
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        nativeInit(this);
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @param delegate Delegate to handle events.
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public void setDelegate(Delegate delegate) {
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mDelegate = delegate;
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @param window Represents the activity window.
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public void setWindow(WindowAndroid window) {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        assert window != null;
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mWindow = window;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mContentViewRenderView = new ContentViewRenderView(getContext()) {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            @Override
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            protected void onReadyToRender() {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                setOverlayVideoMode(true);
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            }
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        };
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mContentViewRenderView.onNativeLibraryLoaded(window);
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // Setting the background color to black avoids rendering a white splash screen
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // before the players are loaded. See crbug/307113 for details.
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mContentViewRenderView.setSurfaceViewBackgroundColor(Color.BLACK);
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @return The window used to generate all shells.
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public WindowAndroid getWindow() {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return mWindow;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @return The currently visible shell view or null if one is not showing.
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public CastWindowAndroid getActiveCastWindow() {
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return mActiveCastWindow;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Creates a new shell pointing to the specified URL.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @param url The URL the shell should load upon creation.
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @return Pointer of native cast shell instance.
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public long launchCastWindow(String url) {
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return nativeLaunchCastWindow(url);
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    /**
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Stops a native cast shell instance created by {@link #launchCastWindow(String)}.
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @param nativeCastWindow Pointer of native cast shell instance returned
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     *        by {@link #launchCastWindow(String)}.
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @param gracefully Whether or not to call RVH::ClosePage to deliver unload event.
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * @see #launchCastWindow(String)
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     */
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public void stopCastWindow(long nativeCastWindow, boolean gracefully) {
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        nativeStopCastWindow(nativeCastWindow, gracefully);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    @SuppressWarnings("unused")
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    @CalledByNative
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private Object createCastWindow() {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        assert mContentViewRenderView != null;
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        LayoutInflater inflater =
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CastWindowAndroid shellView =
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                (CastWindowAndroid) inflater.inflate(R.layout.cast_window_view, null);
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shellView.setWindow(mWindow);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (mActiveCastWindow != null) closeCastWindow(mActiveCastWindow);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shellView.setContentViewRenderView(mContentViewRenderView);
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        addView(shellView, new FrameLayout.LayoutParams(
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        mActiveCastWindow = shellView;
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ContentViewCore contentViewCore = mActiveCastWindow.getContentViewCore();
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (contentViewCore != null) {
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            mContentViewRenderView.setCurrentContentViewCore(contentViewCore);
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            contentViewCore.onShow();
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (mDelegate != null) {
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            mDelegate.onCreated();
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return shellView;
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    @SuppressWarnings("unused")
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    @CalledByNative
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private void closeCastWindow(CastWindowAndroid shellView) {
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (shellView == mActiveCastWindow) mActiveCastWindow = null;
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ContentViewCore contentViewCore = shellView.getContentViewCore();
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (contentViewCore != null) contentViewCore.onHide();
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shellView.setContentViewRenderView(null);
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shellView.setWindow(null);
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        removeView(shellView);
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (mDelegate != null) {
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            mDelegate.onClosed();
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private static native void nativeInit(Object shellManagerInstance);
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private static native long nativeLaunchCastWindow(String url);
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private static native void nativeStopCastWindow(long pointerOfNativeCastWindow,
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            boolean gracefully);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public static native void nativeEnableDevTools(boolean enable);
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
158