diff options
author | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-02 06:36:31 +0000 |
---|---|---|
committer | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-02 06:36:31 +0000 |
commit | adcff2dfcc7d4916ccc322aa53d35098b66c026a (patch) | |
tree | 47ade2efe9accbe03572f81d4030bd194909ee87 /content/browser/android | |
parent | a334864d9687516534a1b0cc8c18208a63c9e136 (diff) | |
download | chromium_src-adcff2dfcc7d4916ccc322aa53d35098b66c026a.zip chromium_src-adcff2dfcc7d4916ccc322aa53d35098b66c026a.tar.gz chromium_src-adcff2dfcc7d4916ccc322aa53d35098b66c026a.tar.bz2 |
Extract metadata for media elements
In our current html5 media implemtation, we pretend everything is loaded and gave a temporary duration of 100 seconds to WebKit.
However, this will break things if developer do sth like video.seek(video.duration). Also, width and height information are not available.
This change adds a thread in browser process to extract media metadata from the elements, before reporting to WebKit that media is loaded.
This only works if wifi or ethernet is available.
Review URL: https://chromiumcodereview.appspot.com/12518035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191786 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/android')
5 files changed, 63 insertions, 12 deletions
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc index 1915337..4aa5c86 100644 --- a/content/browser/android/browser_jni_registrar.cc +++ b/content/browser/android/browser_jni_registrar.cc @@ -17,6 +17,7 @@ #include "content/browser/android/download_controller_android_impl.h" #include "content/browser/android/interstitial_page_delegate_android.h" #include "content/browser/android/load_url_params.h" +#include "content/browser/android/media_resource_getter_impl.h" #include "content/browser/android/surface_texture_peer_browser_impl.h" #include "content/browser/android/touch_point.h" #include "content/browser/android/tracing_intent_handler.h" @@ -44,6 +45,8 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = { { "InterstitialPageDelegateAndroid", content::InterstitialPageDelegateAndroid ::RegisterInterstitialPageDelegateAndroid }, + { "MediaResourceGetterImpl", + content::MediaResourceGetterImpl::RegisterMediaResourceGetter }, { "LoadUrlParams", content::RegisterLoadUrlParams }, { "RegisterImeAdapter", content::RegisterImeAdapter }, { "TouchPoint", content::RegisterTouchPoint }, diff --git a/content/browser/android/media_player_manager_android.cc b/content/browser/android/media_player_manager_android.cc index 7375ff7..ef65028 100644 --- a/content/browser/android/media_player_manager_android.cc +++ b/content/browser/android/media_player_manager_android.cc @@ -123,7 +123,7 @@ void MediaPlayerManagerAndroid::OnInitialize( base::Unretained(this)), base::Bind(&MediaPlayerManagerAndroid::OnBufferingUpdate, base::Unretained(this)), - base::Bind(&MediaPlayerManagerAndroid::OnPrepared, + base::Bind(&MediaPlayerManagerAndroid::OnMediaMetadataChanged, base::Unretained(this)), base::Bind(&MediaPlayerManagerAndroid::OnPlaybackComplete, base::Unretained(this)), @@ -133,10 +133,6 @@ void MediaPlayerManagerAndroid::OnInitialize( base::Unretained(this)), base::Bind(&MediaPlayerManagerAndroid::OnMediaInterrupted, base::Unretained(this)))); - - // Send a MediaPrepared message to webkit so that Load() can finish. - Send(new MediaPlayerMsg_MediaPrepared( - routing_id(), player_id, GetPlayer(player_id)->GetDuration())); } void MediaPlayerManagerAndroid::OnStart(int player_id) { @@ -238,9 +234,11 @@ MediaPlayerBridge* MediaPlayerManagerAndroid::GetFullscreenPlayer() { return GetPlayer(fullscreen_player_id_); } -void MediaPlayerManagerAndroid::OnPrepared(int player_id, - base::TimeDelta duration) { - Send(new MediaPlayerMsg_MediaPrepared(routing_id(), player_id, duration)); +void MediaPlayerManagerAndroid::OnMediaMetadataChanged( + int player_id, base::TimeDelta duration, int width, int height, + bool success) { + Send(new MediaPlayerMsg_MediaMetadataChanged( + routing_id(), player_id, duration, width, height, success)); if (fullscreen_player_id_ != -1) video_view_.UpdateMediaMetadata(); } diff --git a/content/browser/android/media_player_manager_android.h b/content/browser/android/media_player_manager_android.h index 2500086..89d2a51 100644 --- a/content/browser/android/media_player_manager_android.h +++ b/content/browser/android/media_player_manager_android.h @@ -49,7 +49,8 @@ class MediaPlayerManagerAndroid void OnTimeUpdate(int player_id, base::TimeDelta current_time); // Callbacks needed by media::MediaPlayerBridge. - void OnPrepared(int player_id, base::TimeDelta duration); + void OnMediaMetadataChanged(int player_id, base::TimeDelta duration, + int width, int height, bool success); void OnPlaybackComplete(int player_id); void OnMediaInterrupted(int player_id); void OnBufferingUpdate(int player_id, int percentage); diff --git a/content/browser/android/media_resource_getter_impl.cc b/content/browser/android/media_resource_getter_impl.cc index 2f5d4ee..8c1177a 100644 --- a/content/browser/android/media_resource_getter_impl.cc +++ b/content/browser/android/media_resource_getter_impl.cc @@ -4,8 +4,11 @@ #include "content/browser/android/media_resource_getter_impl.h" +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" #include "base/bind.h" #include "base/path_service.h" +#include "base/threading/sequenced_worker_pool.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/fileapi/browser_file_system_helper.h" #include "content/public/browser/browser_context.h" @@ -13,6 +16,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" #include "googleurl/src/gurl.h" +#include "jni/MediaResourceGetter_jni.h" #include "net/cookies/cookie_monster.h" #include "net/cookies/cookie_store.h" #include "net/url_request/url_request_context.h" @@ -27,6 +31,31 @@ static void ReturnResultOnUIThread( BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); } +// Get the metadata from a media URL. When finished, a task is posted to the UI +// thread to run the callback function. +static void GetMediaMetadata( + const std::string& url, const std::string& cookies, + const media::MediaResourceGetter::ExtractMediaMetadataCB& callback) { + JNIEnv* env = base::android::AttachCurrentThread(); + + base::android::ScopedJavaLocalRef<jstring> j_url_string = + base::android::ConvertUTF8ToJavaString(env, url); + base::android::ScopedJavaLocalRef<jstring> j_cookies = + base::android::ConvertUTF8ToJavaString(env, cookies); + jobject j_context = base::android::GetApplicationContext(); + base::android::ScopedJavaLocalRef<jobject> j_metadata = + Java_MediaResourceGetter_extractMediaMetadata( + env, j_context, j_url_string.obj(), j_cookies.obj()); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(callback, base::TimeDelta::FromMilliseconds( + Java_MediaMetadata_getDurationInMilliseconds( + env, j_metadata.obj())), + Java_MediaMetadata_getWidth(env, j_metadata.obj()), + Java_MediaMetadata_getHeight(env, j_metadata.obj()), + Java_MediaMetadata_isSuccess(env, j_metadata.obj()))); +} + // The task object that retrieves cookie on the IO thread. // TODO(qinmin): refactor this class to make the code reusable by others as // there are lots of duplicated functionalities elsewhere. @@ -184,9 +213,9 @@ MediaResourceGetterImpl::MediaResourceGetterImpl( MediaResourceGetterImpl::~MediaResourceGetterImpl() {} -void MediaResourceGetterImpl::GetCookies(const GURL& url, - const GURL& first_party_for_cookies, - const GetCookieCB& callback) { +void MediaResourceGetterImpl::GetCookies( + const GURL& url, const GURL& first_party_for_cookies, + const GetCookieCB& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); scoped_refptr<CookieGetterTask> task = new CookieGetterTask( browser_context_, renderer_id_, routing_id_); @@ -230,4 +259,18 @@ void MediaResourceGetterImpl::GetPlatformPathCallback( callback.Run(platform_path); } +void MediaResourceGetterImpl::ExtractMediaMetadata( + const std::string& url, const std::string& cookies, + const ExtractMediaMetadataCB& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); + pool->PostWorkerTask( + FROM_HERE, base::Bind(&GetMediaMetadata, url, cookies, callback)); +} + +// static +bool MediaResourceGetterImpl::RegisterMediaResourceGetter(JNIEnv* env) { + return RegisterNativesImpl(env); +} + } // namespace content diff --git a/content/browser/android/media_resource_getter_impl.h b/content/browser/android/media_resource_getter_impl.h index 20ba44f..1d15244 100644 --- a/content/browser/android/media_resource_getter_impl.h +++ b/content/browser/android/media_resource_getter_impl.h @@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_ANDROID_MEDIA_RESOURCE_GETTER_IMPL_H_ #define CONTENT_BROWSER_ANDROID_MEDIA_RESOURCE_GETTER_IMPL_H_ +#include <jni.h> #include <string> #include "base/memory/ref_counted.h" @@ -46,6 +47,11 @@ class MediaResourceGetterImpl : public media::MediaResourceGetter { virtual void GetPlatformPathFromFileSystemURL( const GURL& url, const GetPlatformPathCB& callback) OVERRIDE; + virtual void ExtractMediaMetadata( + const std::string& url, const std::string& cookies, + const ExtractMediaMetadataCB& callback) OVERRIDE; + + static bool RegisterMediaResourceGetter(JNIEnv* env); private: // Called when GetCookies() finishes. |