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.
This commit is contained in:
@@ -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.
|
||||
|
||||
129
core/java/android/webkit/ViewManager.java
Normal file
129
core/java/android/webkit/ViewManager.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user