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

Commit 0a5ce01e authored by Patrick Scott's avatar Patrick Scott
Browse files

Basic changes to get embedded video working.

Add the ViewManager class to handle child views within a WebView. This class
attaches and removes the views in the UI thread. It also scales the layout
params based on the scale of the WebView.
parent 3042bb62
Loading
Loading
Loading
Loading
+34 −25
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.util.Log;
import android.util.Log;
import android.view.View;
import android.view.View;
import android.webkit.ViewManager.ChildView;
import android.widget.MediaController;
import android.widget.MediaController;
import android.widget.VideoView;
import android.widget.VideoView;


@@ -46,8 +47,6 @@ class HTML5VideoViewProxy extends Handler {


    // The singleton instance.
    // The singleton instance.
    private static HTML5VideoViewProxy sInstance;
    private static HTML5VideoViewProxy sInstance;
    // The VideoView driven via this proxy.
    private VideoView mVideoView;
    // The context object used to initialize the VideoView and the
    // The context object used to initialize the VideoView and the
    // MediaController.
    // MediaController.
    private Context mContext;
    private Context mContext;
@@ -61,12 +60,6 @@ class HTML5VideoViewProxy extends Handler {
        super(Looper.getMainLooper());
        super(Looper.getMainLooper());
        // Save the context object.
        // Save the context object.
        mContext = context;
        mContext = context;
        // Send a message to the UI thread to create the VideoView.
        // This need to be done on the UI thread, or else the
        // event Handlers used by the VideoView and MediaController
        // will be attached to the wrong thread.
        Message message = obtainMessage(INIT);
        sendMessage(message);
    }
    }


    @Override
    @Override
@@ -74,25 +67,22 @@ class HTML5VideoViewProxy extends Handler {
        // This executes on the UI thread.
        // This executes on the UI thread.
        switch (msg.what) {
        switch (msg.what) {
            case INIT:
            case INIT:
                ChildView child = (ChildView) msg.obj;
                // Create the video view and set a default controller.
                // Create the video view and set a default controller.
                mVideoView = new VideoView(mContext);
                VideoView v = new VideoView(mContext);
                mVideoView.setMediaController(new MediaController(mContext));
                // This is needed because otherwise there will be a black square
                // stuck on the screen.
                v.setWillNotDraw(false);
                v.setMediaController(new MediaController(mContext));
                child.mView = v;
                break;
                break;
            case PLAY:
            case PLAY:
                // Check if the fullscreen video view is currently playing.
                // If it is, ignore the message.
                if (!mVideoView.isPlaying()) {
                HashMap<String, Object> map =
                HashMap<String, Object> map =
                        (HashMap<String, Object>) msg.obj;
                        (HashMap<String, Object>) msg.obj;
                String url = (String) map.get("url");
                String url = (String) map.get("url");
                    WebView webview = (WebView) map.get("webview");
                VideoView view = (VideoView) map.get("view");
                    WebChromeClient client = webview.getWebChromeClient();
                view.setVideoURI(Uri.parse(url));
                    if (client != null) {
                view.start();
                        mVideoView.setVideoURI(Uri.parse(url));
                        mVideoView.start();
                        client.onShowCustomView(mVideoView);
                    }
                }
                break;
                break;
        }
        }
    }
    }
@@ -102,16 +92,35 @@ class HTML5VideoViewProxy extends Handler {
     * @param url is the URL of the video stream.
     * @param url is the URL of the video stream.
     * @param webview is the WebViewCore that is requesting the playback.
     * @param webview is the WebViewCore that is requesting the playback.
     */
     */
    public void play(String url, WebViewCore webviewCore) {
    public void play(String url, ChildView child) {
        // We need to know the webview that is requesting the playback.
        // We need to know the webview that is requesting the playback.
        Message message = obtainMessage(PLAY);
        Message message = obtainMessage(PLAY);
        HashMap<String, Object> map = new HashMap();
        HashMap<String, Object> map = new HashMap();
        map.put("url", url);
        map.put("url", url);
        map.put("webview", webviewCore.getWebView());
        map.put("view", child.mView);
        message.obj = map;
        message.obj = map;
        sendMessage(message);
        sendMessage(message);
    }
    }


    public ChildView createView(WebViewCore core) {
        WebView w = core.getWebView();
        if (w == null) {
            return null;
        }
        ChildView child = w.mViewManager.createView();
        sendMessage(obtainMessage(INIT, child));
        return child;
    }

    public void attachView(ChildView child, int x, int y, int width,
            int height) {
        child.attachView(x, y, width, height);
    }

    public void removeView(ChildView child) {
        child.removeView();
    }

    /**
    /**
     * The factory for HTML5VideoViewProxy instances. Right now,
     * The factory for HTML5VideoViewProxy instances. Right now,
     * it only produces a singleton.
     * it only produces a singleton.
+129 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2009 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 android.webkit;

import android.content.Context;
import android.view.View;
import android.widget.AbsoluteLayout;

import java.util.ArrayList;

class ViewManager {
    private final WebView mWebView;
    private final ArrayList<ChildView> mChildren = new ArrayList<ChildView>();
    private boolean mHidden;

    class ChildView {
        int x;
        int y;
        int width;
        int height;
        View mView; // generic view to show

        ChildView() {
        }

        void setBounds(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        void attachView(int x, int y, int width, int height) {
            if (mView == null) {
                return;
            }
            setBounds(x, y, width, height);
            final AbsoluteLayout.LayoutParams lp =
                    new AbsoluteLayout.LayoutParams(ctv(width), ctv(height),
                            ctv(x), ctv(y));
            mWebView.mPrivateHandler.post(new Runnable() {
                public void run() {
                    // This method may be called multiple times. If the view is
                    // already attached, just set the new LayoutParams,
                    // otherwise attach the view and add it to the list of
                    // children.
                    if (mView.getParent() != null) {
                        mView.setLayoutParams(lp);
                    } else {
                        mWebView.addView(mView, lp);
                        mChildren.add(ChildView.this);
                    }
                }
            });
        }

        void removeView() {
            if (mView == null) {
                return;
            }
            mWebView.mPrivateHandler.post(new Runnable() {
                public void run() {
                    mWebView.removeView(mView);
                    mChildren.remove(ChildView.this);
                }
            });
        }
    }

    ViewManager(WebView w) {
        mWebView = w;
    }

    ChildView createView() {
        return new ChildView();
    }

    // contentToView shorthand.
    private int ctv(int val) {
        return mWebView.contentToView(val);
    }

    void scaleAll() {
        for (ChildView v : mChildren) {
            View view = v.mView;
            AbsoluteLayout.LayoutParams lp =
                    (AbsoluteLayout.LayoutParams) view.getLayoutParams();
            lp.width = ctv(v.width);
            lp.height = ctv(v.height);
            lp.x = ctv(v.x);
            lp.y = ctv(v.y);
            view.setLayoutParams(lp);
        }
    }

    void hideAll() {
        if (mHidden) {
            return;
        }
        for (ChildView v : mChildren) {
            v.mView.setVisibility(View.GONE);
        }
        mHidden = true;
    }

    void showAll() {
        if (!mHidden) {
            return;
        }
        for (ChildView v : mChildren) {
            v.mView.setVisibility(View.VISIBLE);
        }
        mHidden = false;
    }
}
+14 −1
Original line number Original line Diff line number Diff line
@@ -308,6 +308,9 @@ public class WebView extends AbsoluteLayout
    // more key events.
    // more key events.
    private int mTextGeneration;
    private int mTextGeneration;


    // Used by WebViewCore to create child views.
    /* package */ final ViewManager mViewManager;

    // The list of loaded plugins.
    // The list of loaded plugins.
    private static PluginList sPluginList;
    private static PluginList sPluginList;


@@ -710,6 +713,8 @@ public class WebView extends AbsoluteLayout
        mDatabase = WebViewDatabase.getInstance(context);
        mDatabase = WebViewDatabase.getInstance(context);
        mScroller = new Scroller(context);
        mScroller = new Scroller(context);


        mViewManager = new ViewManager(this);

        mZoomButtonsController = new ZoomButtonsController(this);
        mZoomButtonsController = new ZoomButtonsController(this);
        mZoomButtonsController.setOnZoomListener(mZoomListener);
        mZoomButtonsController.setOnZoomListener(mZoomListener);
        // ZoomButtonsController positions the buttons at the bottom, but in
        // ZoomButtonsController positions the buttons at the bottom, but in
@@ -1688,7 +1693,7 @@ public class WebView extends AbsoluteLayout
        return Math.round(x * mInvActualScale);
        return Math.round(x * mInvActualScale);
    }
    }


    private int contentToView(int x) {
    /*package*/ int contentToView(int x) {
        return Math.round(x * mActualScale);
        return Math.round(x * mActualScale);
    }
    }


@@ -1779,6 +1784,9 @@ public class WebView extends AbsoluteLayout
                mActualScale = scale;
                mActualScale = scale;
                mInvActualScale = 1 / scale;
                mInvActualScale = 1 / scale;


                // Scale all the child views
                mViewManager.scaleAll();

                // as we don't have animation for scaling, don't do animation
                // as we don't have animation for scaling, don't do animation
                // for scrolling, as it causes weird intermediate state
                // for scrolling, as it causes weird intermediate state
                //        pinScrollTo(Math.round(sx), Math.round(sy));
                //        pinScrollTo(Math.round(sx), Math.round(sy));
@@ -2716,6 +2724,8 @@ public class WebView extends AbsoluteLayout
                        - (width >> 1), (int) (scrollFrame.centerY()
                        - (width >> 1), (int) (scrollFrame.centerY()
                        * mActualScale) - (height >> 1));
                        * mActualScale) - (height >> 1));
                mTouchMode = TOUCH_DONE_MODE;
                mTouchMode = TOUCH_DONE_MODE;
                // Show all the child views once we are done.
                mViewManager.showAll();
            } else {
            } else {
                mTouchMode = SCROLL_ZOOM_OUT;
                mTouchMode = SCROLL_ZOOM_OUT;
            }
            }
@@ -2879,6 +2889,8 @@ public class WebView extends AbsoluteLayout
            mTouchMode = TOUCH_DONE_MODE;
            mTouchMode = TOUCH_DONE_MODE;
            return;
            return;
        }
        }
        // Hide the child views while in this mode.
        mViewManager.hideAll();
        startZoomScrollOut();
        startZoomScrollOut();
        mTouchMode = SCROLL_ZOOM_ANIMATION_OUT;
        mTouchMode = SCROLL_ZOOM_ANIMATION_OUT;
        invalidate();
        invalidate();
@@ -3625,6 +3637,7 @@ public class WebView extends AbsoluteLayout
    @Override
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        super.onScrollChanged(l, t, oldl, oldt);

        sendOurVisibleRect();
        sendOurVisibleRect();
    }
    }