HTML5VideoViewProxy.java revision 290c34ac3a36b407b74b42c37501c2d0cdac70ad
16fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu/* 26fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * Copyright (C) 2009 The Android Open Source Project 36fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * 46fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * Licensed under the Apache License, Version 2.0 (the "License"); 56fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * you may not use this file except in compliance with the License. 66fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * You may obtain a copy of the License at 76fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * 86fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * http://www.apache.org/licenses/LICENSE-2.0 96fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * 106fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * Unless required by applicable law or agreed to in writing, software 116fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * distributed under the License is distributed on an "AS IS" BASIS, 126fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * See the License for the specific language governing permissions and 146fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * limitations under the License. 156fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu */ 166fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 176fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescupackage android.webkit; 186fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 196fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.content.Context; 2064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.graphics.Bitmap; 2164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.graphics.BitmapFactory; 223c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescuimport android.media.MediaPlayer; 233c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescuimport android.media.MediaPlayer.OnPreparedListener; 2464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.media.MediaPlayer.OnCompletionListener; 2564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.media.MediaPlayer.OnErrorListener; 2664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.EventHandler; 2764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.Headers; 2864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.RequestHandle; 2964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.RequestQueue; 3064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.SslCertificate; 3164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.net.http.SslError; 326fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.net.Uri; 336fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.os.Bundle; 346fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.os.Handler; 356fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.os.Looper; 366fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.os.Message; 376fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.util.Log; 383c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescuimport android.view.MotionEvent; 396fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.view.View; 403c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescuimport android.view.ViewGroup; 410a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottimport android.webkit.ViewManager.ChildView; 423c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescuimport android.widget.AbsoluteLayout; 4364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport android.widget.ImageView; 446fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.widget.MediaController; 456fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport android.widget.VideoView; 466fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 4764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport java.io.ByteArrayOutputStream; 4864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescuimport java.io.IOException; 496fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescuimport java.util.HashMap; 50290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescuimport java.util.Map; 516fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 526fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu/** 533c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu * <p>Proxy for HTML5 video views. 546fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu */ 55290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescuclass HTML5VideoViewProxy extends Handler 56290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu implements MediaPlayer.OnPreparedListener, 57290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu MediaPlayer.OnCompletionListener { 586fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu // Logging tag. 596fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu private static final String LOGTAG = "HTML5VideoViewProxy"; 606fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 613c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu // Message Ids for WebCore thread -> UI thread communication. 626fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu private static final int INIT = 100; 636fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu private static final int PLAY = 101; 6464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static final int SET_POSTER = 102; 65290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private static final int SEEK = 103; 66290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private static final int PAUSE = 104; 676fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 6864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Message Ids to be handled on the WebCore thread 69290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private static final int PREPARED = 200; 70290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private static final int ENDED = 201; 7164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 72290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // The C++ MediaPlayerPrivateAndroid object. 73290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu int mNativePointer; 7464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The handler for WebCore thread messages; 7564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private Handler mWebCoreHandler; 763c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu // The WebView instance that created this view. 773c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu private WebView mWebView; 783c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu // The ChildView instance used by the ViewManager. 793c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu private ChildView mChildView; 8064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The poster image to be shown when the video is not playing. 8164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private ImageView mPosterView; 8264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The poster downloader. 8364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private PosterDownloader mPosterDownloader; 84290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // The seek position. 85290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private int mSeekPosition; 8664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // A helper class to control the playback. This executes on the UI thread! 8764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static final class VideoPlayer { 8864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The proxy that is currently playing (if any). 8964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static HTML5VideoViewProxy mCurrentProxy; 9064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The VideoView instance. This is a singleton for now, at least until 9164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // http://b/issue?id=1973663 is fixed. 9264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static VideoView mVideoView; 9364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 9464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static final WebChromeClient.CustomViewCallback mCallback = 9564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu new WebChromeClient.CustomViewCallback() { 9664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void onCustomViewHidden() { 9764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // At this point the videoview is pretty much destroyed. 9864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // It listens to SurfaceHolder.Callback.SurfaceDestroyed event 9964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // which happens when the video view is detached from its parent 10064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // view. This happens in the WebChromeClient before this method 10164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // is invoked. 10264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mCurrentProxy.playbackEnded(); 10364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mCurrentProxy = null; 10464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView = null; 10564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 10664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu }; 10764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 108290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public static void play(String url, int time, HTML5VideoViewProxy proxy, 109290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu WebChromeClient client) { 11064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mCurrentProxy != null) { 11164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Some other video is already playing. Notify the caller that its playback ended. 11264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu proxy.playbackEnded(); 11364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return; 1143c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 11564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mCurrentProxy = proxy; 11664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView = new VideoView(proxy.getContext()); 11764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView.setWillNotDraw(false); 11864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView.setMediaController(new MediaController(proxy.getContext())); 11964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView.setVideoURI(Uri.parse(url)); 120290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mVideoView.setOnCompletionListener(proxy); 121290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mVideoView.setOnPreparedListener(proxy); 122290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mVideoView.seekTo(time); 12364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mVideoView.start(); 12464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu client.onShowCustomView(mVideoView, mCallback); 12564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 126290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 127290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public static void seek(int time, HTML5VideoViewProxy proxy) { 128290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu if (mCurrentProxy == proxy && time >= 0 && mVideoView != null) { 129290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mVideoView.seekTo(time); 130290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 131290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 132290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 133290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public static void pause(HTML5VideoViewProxy proxy) { 134290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu if (mCurrentProxy == proxy && mVideoView != null) { 135290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mVideoView.pause(); 136290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 137290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 138290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 139290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 140290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // A bunch event listeners for our VideoView 141290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // MediaPlayer.OnPreparedListener 142290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public void onPrepared(MediaPlayer mp) { 143290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Message msg = Message.obtain(mWebCoreHandler, PREPARED); 144290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Map<String, Object> map = new HashMap<String, Object>(); 145290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu map.put("dur", new Integer(mp.getDuration())); 146290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu map.put("width", new Integer(mp.getVideoWidth())); 147290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu map.put("height", new Integer(mp.getVideoHeight())); 148290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu msg.obj = map; 149290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mWebCoreHandler.sendMessage(msg); 150290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 151290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 152290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // MediaPlayer.OnCompletionListener; 153290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public void onCompletion(MediaPlayer mp) { 154290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu playbackEnded(); 155290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 156290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 157290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public void playbackEnded() { 158290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Message msg = Message.obtain(mWebCoreHandler, ENDED); 159290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mWebCoreHandler.sendMessage(msg); 16064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 1613c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 16264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Handler for the messages from WebCore thread to the UI thread. 16364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu @Override 16464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void handleMessage(Message msg) { 16564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // This executes on the UI thread. 16664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu switch (msg.what) { 16764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu case INIT: { 16864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterView = new ImageView(mWebView.getContext()); 16964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mChildView.mView = mPosterView; 17064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu break; 1713c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 17264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu case PLAY: { 17364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu String url = (String) msg.obj; 17464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu WebChromeClient client = mWebView.getWebChromeClient(); 17564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (client != null) { 176290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu VideoPlayer.play(url, mSeekPosition, this, client); 17764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 17864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu break; 17964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 18064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu case SET_POSTER: { 18164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu Bitmap poster = (Bitmap) msg.obj; 18264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterView.setImageBitmap(poster); 18364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu break; 18464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 185290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu case SEEK: { 186290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Integer time = (Integer) msg.obj; 187290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mSeekPosition = time; 188290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu VideoPlayer.seek(mSeekPosition, this); 189290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu break; 190290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 191290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu case PAUSE: { 192290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu VideoPlayer.pause(this); 193290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu break; 194290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 19564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 19664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 19764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 19864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Everything below this comment executes on the WebCore thread, except for 19964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // the EventHandler methods, which are called on the network thread. 20064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 20164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // A helper class that knows how to download posters 20264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static final class PosterDownloader implements EventHandler { 20364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The request queue. This is static as we have one queue for all posters. 20464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static RequestQueue mRequestQueue; 20564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private static int mQueueRefCount = 0; 20664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The poster URL 20764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private String mUrl; 20864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The proxy we're doing this for. 20964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private final HTML5VideoViewProxy mProxy; 21064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The poster bytes. We only touch this on the network thread. 21164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private ByteArrayOutputStream mPosterBytes; 21264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The request handle. We only touch this on the WebCore thread. 21364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private RequestHandle mRequestHandle; 21464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The response status code. 21564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private int mStatusCode; 21664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The response headers. 21764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private Headers mHeaders; 21864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The handler to handle messages on the WebCore thread. 21964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private Handler mHandler; 22064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 22164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public PosterDownloader(String url, HTML5VideoViewProxy proxy) { 22264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mUrl = url; 22364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mProxy = proxy; 22464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mHandler = new Handler(); 22564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 22664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Start the download. Called on WebCore thread. 22764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void start() { 22864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu retainQueue(); 22964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestHandle = mRequestQueue.queueRequest(mUrl, "GET", null, this, null, 0); 23064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 23164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Cancel the download if active and release the queue. Called on WebCore thread. 23264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void cancelAndReleaseQueue() { 23364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mRequestHandle != null) { 23464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestHandle.cancel(); 23564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestHandle = null; 23664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 23764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu releaseQueue(); 23864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 23964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // EventHandler methods. Executed on the network thread. 24064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void status(int major_version, 24164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu int minor_version, 24264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu int code, 24364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu String reason_phrase) { 24464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mStatusCode = code; 24564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 2463c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 24764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void headers(Headers headers) { 24864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mHeaders = headers; 2493c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 2503c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 25164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void data(byte[] data, int len) { 25264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mPosterBytes == null) { 25364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterBytes = new ByteArrayOutputStream(); 2543c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 25564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterBytes.write(data, 0, len); 2563c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 2573c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 25864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void endData() { 25964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mStatusCode == 200) { 26064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mPosterBytes.size() > 0) { 26164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu Bitmap poster = BitmapFactory.decodeByteArray( 26264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterBytes.toByteArray(), 0, mPosterBytes.size()); 26364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (poster != null) { 26464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mProxy.doSetPoster(poster); 26564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 26664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 26764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu cleanup(); 26864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } else if (mStatusCode >= 300 && mStatusCode < 400) { 26964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // We have a redirect. 27064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mUrl = mHeaders.getLocation(); 27164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mUrl != null) { 27264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mHandler.post(new Runnable() { 27364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void run() { 27464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mRequestHandle != null) { 27564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestHandle.setupRedirect(mUrl, mStatusCode, 27664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu new HashMap<String, String>()); 27764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 27864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 27964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu }); 28064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 28164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 2823c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 2833c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 28464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void certificate(SslCertificate certificate) { 28564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Don't care. 2863c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 2873c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 28864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void error(int id, String description) { 28964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu cleanup(); 29064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 29164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 29264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public boolean handleSslErrorRequest(SslError error) { 29364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Don't care. If this happens, data() will never be called so 29464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // mPosterBytes will never be created, so no need to call cleanup. 29564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return false; 29664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 29764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Tears down the poster bytes stream. Called on network thread. 29864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private void cleanup() { 29964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mPosterBytes != null) { 30064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu try { 30164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterBytes.close(); 30264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } catch (IOException ignored) { 30364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Ignored. 30464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } finally { 30564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterBytes = null; 30664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 3073c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 30864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 30964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 31064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Queue management methods. Called on WebCore thread. 31164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private void retainQueue() { 31264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mRequestQueue == null) { 31364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestQueue = new RequestQueue(mProxy.getContext()); 3143c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 31564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mQueueRefCount++; 3163c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 3173c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu 31864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private void releaseQueue() { 31964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mQueueRefCount == 0) { 32064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return; 32164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 32264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (--mQueueRefCount == 0) { 32364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestQueue.shutdown(); 32464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mRequestQueue = null; 32564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 3263c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 3273c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 3286fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 3296fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu /** 3306fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * Private constructor. 331290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu * @param webView is the WebView that hosts the video. 332290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu * @param nativePtr is the C++ pointer to the MediaPlayerPrivate object. 3336fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu */ 334290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private HTML5VideoViewProxy(WebView webView, int nativePtr) { 3356fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu // This handler is for the main (UI) thread. 3366fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu super(Looper.getMainLooper()); 3373c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu // Save the WebView object. 3383c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu mWebView = webView; 339290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu // Save the native ptr 340290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu mNativePointer = nativePtr; 34164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // create the message handler for this thread 34264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu createWebCoreHandler(); 3436fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu } 3446fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 34564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private void createWebCoreHandler() { 34664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mWebCoreHandler = new Handler() { 34764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu @Override 34864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void handleMessage(Message msg) { 34964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu switch (msg.what) { 350290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu case PREPARED: { 351290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Map<String, Object> map = (Map<String, Object>) msg.obj; 352290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Integer duration = (Integer) map.get("dur"); 353290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Integer width = (Integer) map.get("width"); 354290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Integer height = (Integer) map.get("height"); 355290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu nativeOnPrepared(duration.intValue(), width.intValue(), 356290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu height.intValue(), mNativePointer); 357290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu break; 358290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 359290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu case ENDED: 360290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu nativeOnEnded(mNativePointer); 361290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu break; 3623c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 36364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 36464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu }; 36564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 36664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 36764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu private void doSetPoster(Bitmap poster) { 36864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (poster == null) { 36964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return; 3706fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu } 37164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Send the bitmap over to the UI thread. 37264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu Message message = obtainMessage(SET_POSTER); 37364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu message.obj = poster; 37464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu sendMessage(message); 3756fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu } 3766fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 37764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public Context getContext() { 37864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return mWebView.getContext(); 37964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 38064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 38164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // The public methods below are all called from WebKit only. 3826fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu /** 3836fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * Play a video stream. 3846fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * @param url is the URL of the video stream. 3856fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu */ 3863c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu public void play(String url) { 38764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (url == null) { 38864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return; 38964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 3906fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu Message message = obtainMessage(PLAY); 39164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu message.obj = url; 3926fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu sendMessage(message); 3936fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu } 3946fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu 39564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu /** 396290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu * Seek into the video stream. 397290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu * @param time is the position in the video stream. 398290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu */ 399290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public void seek(int time) { 400290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Message message = obtainMessage(SEEK); 401290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu message.obj = new Integer(time); 402290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu sendMessage(message); 403290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 404290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 405290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu /** 406290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu * Pause the playback. 407290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu */ 408290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public void pause() { 409290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu Message message = obtainMessage(PAUSE); 410290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu sendMessage(message); 411290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu } 412290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 413290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu /** 41464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * Create the child view that will cary the poster. 41564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu */ 4163c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu public void createView() { 4173c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu mChildView = mWebView.mViewManager.createView(); 4183c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu sendMessage(obtainMessage(INIT)); 4190a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott } 4200a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott 42164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu /** 42264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * Attach the poster view. 42364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * @param x, y are the screen coordinates where the poster should be hung. 42464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * @param width, height denote the size of the poster. 42564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu */ 4263c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu public void attachView(int x, int y, int width, int height) { 4273c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu if (mChildView == null) { 4283c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu return; 4293c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 4303c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu mChildView.attachView(x, y, width, height); 4310a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott } 4320a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott 43364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu /** 43464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * Remove the child view and, thus, the poster. 43564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu */ 4363c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu public void removeView() { 4373c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu if (mChildView == null) { 4383c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu return; 4393c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu } 4403c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu mChildView.removeView(); 44164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // This is called by the C++ MediaPlayerPrivate dtor. 44264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Cancel any active poster download. 44364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mPosterDownloader != null) { 44464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterDownloader.cancelAndReleaseQueue(); 44564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 44664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 44764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu 44864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu /** 44964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * Load the poster image. 45064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu * @param url is the URL of the poster image. 45164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu */ 45264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu public void loadPoster(String url) { 45364b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (url == null) { 45464b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu return; 45564b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 45664b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Cancel any active poster download. 45764b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu if (mPosterDownloader != null) { 45864b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterDownloader.cancelAndReleaseQueue(); 45964b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu } 46064b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu // Load the poster asynchronously 46164b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterDownloader = new PosterDownloader(url, this); 46264b86a1e8b6679ed10ecf344abcaebc8412b2efbAndrei Popescu mPosterDownloader.start(); 4630a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott } 4640a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott 4656fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu /** 4663c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu * The factory for HTML5VideoViewProxy instances. 4676fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * @param webViewCore is the WebViewCore that is requesting the proxy. 4686fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu * 4693c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu * @return a new HTML5VideoViewProxy object. 4706fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu */ 471290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu public static HTML5VideoViewProxy getInstance(WebViewCore webViewCore, int nativePtr) { 472290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu return new HTML5VideoViewProxy(webViewCore.getWebView(), nativePtr); 4736fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu } 474290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu 475290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private native void nativeOnPrepared(int duration, int width, int height, int nativePointer); 476290c34ac3a36b407b74b42c37501c2d0cdac70adAndrei Popescu private native void nativeOnEnded(int nativePointer); 4776fa2958059a08390ed2b87b8572f8847ad9999e4Andrei Popescu} 478