diff options
author | Patrick Scott <phanna@android.com> | 2009-07-02 08:56:10 -0400 |
---|---|---|
committer | Patrick Scott <phanna@android.com> | 2009-07-06 14:08:45 -0400 |
commit | 0a5ce01eda210f83619ada0603a80fd883512fe9 (patch) | |
tree | 2fd3ae3be6730a58e97a5448dde5505e423d609b /core/java/android | |
parent | 3042bb623870b877e18dabb07c31b5b8f45afa1d (diff) | |
download | frameworks_base-0a5ce01eda210f83619ada0603a80fd883512fe9.zip frameworks_base-0a5ce01eda210f83619ada0603a80fd883512fe9.tar.gz frameworks_base-0a5ce01eda210f83619ada0603a80fd883512fe9.tar.bz2 |
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.
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/webkit/HTML5VideoViewProxy.java | 59 | ||||
-rw-r--r-- | core/java/android/webkit/ViewManager.java | 129 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 15 |
3 files changed, 177 insertions, 26 deletions
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java index 973cb01..5b2c0e2 100644 --- a/core/java/android/webkit/HTML5VideoViewProxy.java +++ b/core/java/android/webkit/HTML5VideoViewProxy.java @@ -24,6 +24,7 @@ import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; +import android.webkit.ViewManager.ChildView; import android.widget.MediaController; import android.widget.VideoView; @@ -46,8 +47,6 @@ class HTML5VideoViewProxy extends Handler { // The singleton instance. private static HTML5VideoViewProxy sInstance; - // The VideoView driven via this proxy. - private VideoView mVideoView; // The context object used to initialize the VideoView and the // MediaController. private Context mContext; @@ -61,12 +60,6 @@ class HTML5VideoViewProxy extends Handler { super(Looper.getMainLooper()); // Save the context object. 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 @@ -74,25 +67,22 @@ class HTML5VideoViewProxy extends Handler { // This executes on the UI thread. switch (msg.what) { case INIT: + ChildView child = (ChildView) msg.obj; // Create the video view and set a default controller. - mVideoView = new VideoView(mContext); - mVideoView.setMediaController(new MediaController(mContext)); + VideoView v = new VideoView(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; 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; - String url = (String) map.get("url"); - WebView webview = (WebView) map.get("webview"); - WebChromeClient client = webview.getWebChromeClient(); - if (client != null) { - mVideoView.setVideoURI(Uri.parse(url)); - mVideoView.start(); - client.onShowCustomView(mVideoView); - } - } + String url = (String) map.get("url"); + VideoView view = (VideoView) map.get("view"); + view.setVideoURI(Uri.parse(url)); + view.start(); break; } } @@ -102,16 +92,35 @@ class HTML5VideoViewProxy extends Handler { * @param url is the URL of the video stream. * @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. Message message = obtainMessage(PLAY); HashMap<String, Object> map = new HashMap(); map.put("url", url); - map.put("webview", webviewCore.getWebView()); + map.put("view", child.mView); message.obj = map; 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, * it only produces a singleton. diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java new file mode 100644 index 0000000..476e85c --- /dev/null +++ b/core/java/android/webkit/ViewManager.java @@ -0,0 +1,129 @@ +/* + * 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; + } +} diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 57b9ac3..61c0cb9 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -308,6 +308,9 @@ public class WebView extends AbsoluteLayout // more key events. private int mTextGeneration; + // Used by WebViewCore to create child views. + /* package */ final ViewManager mViewManager; + // The list of loaded plugins. private static PluginList sPluginList; @@ -710,6 +713,8 @@ public class WebView extends AbsoluteLayout mDatabase = WebViewDatabase.getInstance(context); mScroller = new Scroller(context); + mViewManager = new ViewManager(this); + mZoomButtonsController = new ZoomButtonsController(this); mZoomButtonsController.setOnZoomListener(mZoomListener); // ZoomButtonsController positions the buttons at the bottom, but in @@ -1688,7 +1693,7 @@ public class WebView extends AbsoluteLayout return Math.round(x * mInvActualScale); } - private int contentToView(int x) { + /*package*/ int contentToView(int x) { return Math.round(x * mActualScale); } @@ -1779,6 +1784,9 @@ public class WebView extends AbsoluteLayout mActualScale = scale; mInvActualScale = 1 / scale; + // Scale all the child views + mViewManager.scaleAll(); + // as we don't have animation for scaling, don't do animation // for scrolling, as it causes weird intermediate state // pinScrollTo(Math.round(sx), Math.round(sy)); @@ -2716,6 +2724,8 @@ public class WebView extends AbsoluteLayout - (width >> 1), (int) (scrollFrame.centerY() * mActualScale) - (height >> 1)); mTouchMode = TOUCH_DONE_MODE; + // Show all the child views once we are done. + mViewManager.showAll(); } else { mTouchMode = SCROLL_ZOOM_OUT; } @@ -2879,6 +2889,8 @@ public class WebView extends AbsoluteLayout mTouchMode = TOUCH_DONE_MODE; return; } + // Hide the child views while in this mode. + mViewManager.hideAll(); startZoomScrollOut(); mTouchMode = SCROLL_ZOOM_ANIMATION_OUT; invalidate(); @@ -3625,6 +3637,7 @@ public class WebView extends AbsoluteLayout @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); + sendOurVisibleRect(); } |