Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: media/base/android/media_player_bridge.cc

Issue 10919075: Move android mediaplayer from render process to browser process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add the missing cookies_retriever.h file Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/android/media_player_bridge.h" 5 #include "media/base/android/media_player_bridge.h"
6 6
7 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 8 #include "base/android/jni_string.h"
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/stringprintf.h" 11 #include "base/stringprintf.h"
12 12 #include "base/message_loop_proxy.h"
13 // Auto generated jni class from MediaPlayerListener.java. 13 #include "media/base/android/cookies_retriever.h"
14 // Check base/android/jni_generator/golden_sample_for_tests_jni.h for example. 14 #include "media/base/android/media_player_bridge_manager.h"
15 #include "jni/MediaPlayerListener_jni.h" 15 #include "media/base/android/media_player_listener.h"
16 16
17 using base::android::AttachCurrentThread; 17 using base::android::AttachCurrentThread;
18 using base::android::CheckException; 18 using base::android::CheckException;
19 using base::android::ConvertUTF8ToJavaString; 19 using base::android::ConvertUTF8ToJavaString;
20 using base::android::GetClass; 20 using base::android::GetClass;
21 using base::android::GetMethodID; 21 using base::android::GetMethodID;
22 using base::android::JavaRef; 22 using base::android::JavaRef;
23 using base::android::ScopedJavaLocalRef; 23 using base::android::ScopedJavaLocalRef;
24 24
25 // These constants are from the android source tree and need to be kept in 25 // These constants are from the android source tree and need to be kept in
26 // sync with android/media/MediaMetadata.java. 26 // sync with android/media/MediaMetadata.java.
27 static const jint kPauseAvailable = 1; 27 static const jint kPauseAvailable = 1;
28 static const jint kSeekBackwardAvailable = 2; 28 static const jint kSeekBackwardAvailable = 2;
29 static const jint kSeekForwardAvailable = 3; 29 static const jint kSeekForwardAvailable = 3;
30 30
31 // This needs to be kept in sync with android.os.PowerManager 31 // This needs to be kept in sync with android.os.PowerManager
32 static const int kAndroidFullWakeLock = 26; 32 static const int kAndroidFullWakeLock = 26;
33 33
34 // Time update happens every 250ms.
35 static const int kTimeUpdateInterval = 250;
36
37 // Because we create the media player lazily on android, the duration of the
38 // media is initially unknown to us. This makes the user unable to perform
39 // seek. To solve this problem, we use a temporary duration of 100 seconds when
40 // the duration is unknown. And we scale the seek position later when duration
41 // is available.
42 // TODO(qinmin): create a thread and use android MediaMetadataRetriever
43 // class to extract the duration.
44 static const int kTemporaryDuration = 100;
45
34 namespace media { 46 namespace media {
35 47
36 MediaPlayerBridge::MediaPlayerBridge() { 48 MediaPlayerBridge::MediaPlayerBridge(
49 int player_id,
50 const std::string& url,
51 media::CookiesRetriever* cookies_retriever,
52 bool hide_url_log,
53 media::MediaPlayerBridgeManager* manager,
54 const MediaErrorCB& media_error_cb,
55 const VideoSizeChangedCB& video_size_changed_cb,
56 const BufferingUpdateCB& buffering_update_cb,
57 const MediaPreparedCB& media_prepared_cb,
58 const PlaybackCompleteCB& playback_complete_cb,
59 const SeekCompleteCB& seek_complete_cb,
60 const TimeUpdateCB& time_update_cb)
61 : media_error_cb_(media_error_cb),
62 video_size_changed_cb_(video_size_changed_cb),
63 buffering_update_cb_(buffering_update_cb),
64 media_prepared_cb_(media_prepared_cb),
65 playback_complete_cb_(playback_complete_cb),
66 seek_complete_cb_(seek_complete_cb),
67 time_update_cb_(time_update_cb),
68 player_id_(player_id),
69 prepared_(false),
70 pending_play_(false),
71 url_(url),
72 has_cookies_(false),
73 hide_url_log_(hide_url_log),
74 duration_(base::TimeDelta::FromSeconds(kTemporaryDuration)),
75 width_(0),
76 height_(0),
77 can_pause_(true),
78 can_seek_forward_(true),
79 can_seek_backward_(true),
80 manager_(manager),
81 cookies_retriever_(cookies_retriever),
82 listener_(new MediaPlayerListener(base::MessageLoopProxy::current(),
83 AsWeakPtr())) {
84 }
85
86 MediaPlayerBridge::~MediaPlayerBridge() {
87 Release();
88 }
89
90 void MediaPlayerBridge::InitializePlayer() {
37 JNIEnv* env = AttachCurrentThread(); 91 JNIEnv* env = AttachCurrentThread();
38 CHECK(env); 92 CHECK(env);
39 93
40 j_media_player_class_.Reset(GetClass(env, "android/media/MediaPlayer")); 94 j_media_player_class_.Reset(GetClass(env, "android/media/MediaPlayer"));
41 95
42 jmethodID constructor = GetMethodID(env, 96 jmethodID constructor = GetMethodID(env,
43 j_media_player_class_, 97 j_media_player_class_,
44 "<init>", 98 "<init>",
45 "()V"); 99 "()V");
46 ScopedJavaLocalRef<jobject> tmp(env, 100 ScopedJavaLocalRef<jobject> tmp(env,
47 env->NewObject(j_media_player_class_.obj(), constructor)); 101 env->NewObject(j_media_player_class_.obj(), constructor));
48 j_media_player_.Reset(tmp); 102 j_media_player_.Reset(tmp);
49 103
50 ScopedJavaLocalRef<jobject> j_listener( 104 ScopedJavaLocalRef<jobject> j_listener(
51 Java_MediaPlayerListener_create(env, 105 listener_->CreateMediaPlayerListener());
52 reinterpret_cast<intptr_t>(this)));
53 DCHECK(!j_listener.is_null());
54 106
55 // Set it as the various listeners. 107 // Set it as the various listeners.
56 const char* listeners[] = { 108 const char* listeners[] = {
57 "OnBufferingUpdateListener", 109 "OnBufferingUpdateListener",
58 "OnCompletionListener", 110 "OnCompletionListener",
59 "OnErrorListener", 111 "OnErrorListener",
60 "OnInfoListener",
61 "OnPreparedListener", 112 "OnPreparedListener",
62 "OnSeekCompleteListener", 113 "OnSeekCompleteListener",
63 "OnVideoSizeChangedListener", 114 "OnVideoSizeChangedListener",
64 }; 115 };
65 for (unsigned int i = 0; i < arraysize(listeners); ++i) { 116 for (unsigned int i = 0; i < arraysize(listeners); ++i) {
66 std::string signature = StringPrintf("(Landroid/media/MediaPlayer$%s;)V", 117 std::string signature = StringPrintf("(Landroid/media/MediaPlayer$%s;)V",
67 listeners[i]); 118 listeners[i]);
68 std::string method_name = StringPrintf("set%s", listeners[i]); 119 std::string method_name = StringPrintf("set%s", listeners[i]);
69 jmethodID method = GetMethodID(env, 120 jmethodID method = GetMethodID(env,
70 j_media_player_class_, 121 j_media_player_class_,
71 method_name.c_str(), 122 method_name.c_str(),
72 signature.c_str()); 123 signature.c_str());
73 env->CallVoidMethod(j_media_player_.obj(), method, j_listener.obj()); 124 env->CallVoidMethod(j_media_player_.obj(), method, j_listener.obj());
74 CheckException(env); 125 CheckException(env);
75 } 126 }
127
128 jobject j_context = base::android::GetApplicationContext();
129 DCHECK(j_context);
130 jmethodID method = GetMethodID(env, j_media_player_class_,
131 "setWakeMode", "(Landroid/content/Context;I)V");
132 env->CallVoidMethod(j_media_player_.obj(), method, j_context,
133 kAndroidFullWakeLock);
134 CheckException(env);
76 } 135 }
77 136
78 MediaPlayerBridge::~MediaPlayerBridge() { 137 void MediaPlayerBridge::SetVideoSurface(jobject surface) {
79 SetVideoSurface(NULL); 138 if (j_media_player_.is_null() && surface != NULL)
80 CallVoidMethod("release"); 139 Prepare();
140
141 JNIEnv* env = AttachCurrentThread();
142 CHECK(env);
143
144 jmethodID method = GetMethodID(env,
145 j_media_player_class_,
146 "setSurface",
147 "(Landroid/view/Surface;)V");
148 env->CallVoidMethod(j_media_player_.obj(), method, surface);
149 CheckException(env);
81 } 150 }
82 151
83 void MediaPlayerBridge::SetDataSource( 152 void MediaPlayerBridge::Prepare() {
84 const std::string& url, 153 if (j_media_player_.is_null())
85 const std::string& cookies, 154 InitializePlayer();
86 bool hide_url_log) { 155
156 if (has_cookies_) {
157 GetCookiesCallback(cookies_);
158 } else {
159 cookies_retriever_->GetCookiesAsync(url_, base::Bind(
160 &MediaPlayerBridge::GetCookiesCallback, AsWeakPtr()));
161 }
162 }
163
164 void MediaPlayerBridge::GetCookiesCallback(std::string cookies) {
165 cookies_ = cookies;
166 has_cookies_ = true;
167
87 JNIEnv* env = AttachCurrentThread(); 168 JNIEnv* env = AttachCurrentThread();
88 CHECK(env); 169 CHECK(env);
89 170
90 // Create a Java String for the URL. 171 // Create a Java String for the URL.
91 ScopedJavaLocalRef<jstring> j_url_string = ConvertUTF8ToJavaString(env, url); 172 ScopedJavaLocalRef<jstring> j_url_string = ConvertUTF8ToJavaString(env, url_);
92 173
93 // Create the android.net.Uri object. 174 // Create the android.net.Uri object.
94 ScopedJavaLocalRef<jclass> cls(GetClass(env, "android/net/Uri")); 175 ScopedJavaLocalRef<jclass> cls(GetClass(env, "android/net/Uri"));
95 jmethodID method = GetStaticMethodID(env, cls, 176 jmethodID method = GetStaticMethodID(env, cls,
96 "parse", "(Ljava/lang/String;)Landroid/net/Uri;"); 177 "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
97 ScopedJavaLocalRef<jobject> j_uri(env, 178 ScopedJavaLocalRef<jobject> j_uri(env,
98 env->CallStaticObjectMethod(cls.obj(), method, j_url_string.obj())); 179 env->CallStaticObjectMethod(cls.obj(), method, j_url_string.obj()));
99 180
100 // Create the java.util.Map. 181 // Create the java.util.Map.
101 cls.Reset(GetClass(env, "java/util/HashMap")); 182 cls.Reset(GetClass(env, "java/util/HashMap"));
102 jmethodID constructor = GetMethodID(env, cls, "<init>", "()V"); 183 jmethodID constructor = GetMethodID(env, cls, "<init>", "()V");
103 ScopedJavaLocalRef<jobject> j_map(env, 184 ScopedJavaLocalRef<jobject> j_map(env,
104 env->NewObject(cls.obj(), constructor)); 185 env->NewObject(cls.obj(), constructor));
105 jmethodID put_method = GetMethodID(env, cls, "put", 186 jmethodID put_method = GetMethodID(env, cls, "put",
106 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 187 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
107 188
108 // Construct headers that needs to be sent with the url. 189 // Construct headers that needs to be sent with the url.
109 HeadersMap headers; 190 HeadersMap headers;
110 // For incognito mode, we need a header to hide url log. 191 // For incognito mode, we need a header to hide url log.
111 if (hide_url_log) 192 if (hide_url_log_)
112 headers.insert(std::make_pair("x-hide-urls-from-log", "true")); 193 headers.insert(std::make_pair("x-hide-urls-from-log", "true"));
113 // If cookies are present, add them in the header. 194 // If cookies are present, add them in the header.
114 if (!cookies.empty()) 195 if (!cookies_.empty())
115 headers.insert(std::make_pair("Cookie", cookies)); 196 headers.insert(std::make_pair("Cookie", cookies_));
116 197
117 // Fill the Map with the headers. 198 // Fill the Map with the headers.
118 for (HeadersMap::const_iterator iter = headers.begin(); 199 for (HeadersMap::const_iterator iter = headers.begin();
119 iter != headers.end(); ++iter) { 200 iter != headers.end(); ++iter) {
120 ScopedJavaLocalRef<jstring> key = ConvertUTF8ToJavaString(env, iter->first); 201 ScopedJavaLocalRef<jstring> key = ConvertUTF8ToJavaString(env, iter->first);
121 ScopedJavaLocalRef<jstring> value = 202 ScopedJavaLocalRef<jstring> value =
122 ConvertUTF8ToJavaString(env, iter->second); 203 ConvertUTF8ToJavaString(env, iter->second);
123 ScopedJavaLocalRef<jobject> result(env, 204 ScopedJavaLocalRef<jobject> result(env,
124 env->CallObjectMethod(j_map.obj(), put_method, key.obj(), value.obj())); 205 env->CallObjectMethod(j_map.obj(), put_method, key.obj(), value.obj()));
125 } 206 }
126 207
127 jobject j_context = base::android::GetApplicationContext(); 208 jobject j_context = base::android::GetApplicationContext();
128 DCHECK(j_context); 209 DCHECK(j_context);
129 210
130 // Finally- Call the setDataSource method. 211 // Finally- Call the setDataSource method.
131 jmethodID set_data_source = 212 jmethodID set_data_source =
132 GetMethodID(env, j_media_player_class_, "setDataSource", 213 GetMethodID(env, j_media_player_class_, "setDataSource",
133 "(Landroid/content/Context;Landroid/net/Uri;Ljava/util/Map;)V"); 214 "(Landroid/content/Context;Landroid/net/Uri;Ljava/util/Map;)V");
134 DCHECK(set_data_source);
135 env->CallVoidMethod(j_media_player_.obj(), set_data_source, j_context, 215 env->CallVoidMethod(j_media_player_.obj(), set_data_source, j_context,
136 j_uri.obj(), j_map.obj()); 216 j_uri.obj(), j_map.obj());
137 CheckException(env); 217 bool is_data_source_set_ = !base::android::ClearException(env);
218
219 if (is_data_source_set_) {
220 if (manager_)
221 manager_->RequestMediaResources(this);
222 CallVoidMethod("prepareAsync");
223 } else {
224 media_error_cb_.Run(player_id_, MEDIA_ERROR_UNKNOWN);
225 }
138 } 226 }
139 227
140 void MediaPlayerBridge::SetVideoSurface(jobject surface) { 228 void MediaPlayerBridge::Start() {
229 if (j_media_player_.is_null()) {
230 pending_play_ = true;
231 Prepare();
232 } else {
233 if (prepared_)
234 StartInternal();
235 else
236 pending_play_ = true;
237 }
238 }
239
240 void MediaPlayerBridge::Pause() {
241 if (j_media_player_.is_null()) {
242 pending_play_ = false;
243 } else {
244 if (prepared_ && IsPlaying())
245 PauseInternal();
246 else
247 pending_play_ = false;
248 }
249 }
250
251
252 bool MediaPlayerBridge::IsPlaying() {
253 if (!prepared_)
254 return pending_play_;
255
141 JNIEnv* env = AttachCurrentThread(); 256 JNIEnv* env = AttachCurrentThread();
142 CHECK(env); 257 CHECK(env);
143 258
144 jmethodID method = GetMethodID(env, 259 jmethodID method = GetMethodID(env, j_media_player_class_, "isPlaying",
145 j_media_player_class_,
146 "setSurface",
147 "(Landroid/view/Surface;)V");
148 env->CallVoidMethod(j_media_player_.obj(), method, surface);
149 CheckException(env);
150 }
151
152 void MediaPlayerBridge::Prepare(const MediaInfoCB& media_info_cb,
153 const MediaErrorCB& media_error_cb,
154 const VideoSizeChangedCB& video_size_changed_cb,
155 const BufferingUpdateCB& buffering_update_cb,
156 const base::Closure& media_prepared_cb) {
157 media_info_cb_ = media_info_cb;
158 media_error_cb_ = media_error_cb,
159 video_size_changed_cb_ = video_size_changed_cb;
160 buffering_update_cb_ = buffering_update_cb;
161 media_prepared_cb_ = media_prepared_cb;
162 CallVoidMethod("prepareAsync");
163 }
164
165 void MediaPlayerBridge::Start(const base::Closure& playback_complete_cb) {
166 playback_complete_cb_ = playback_complete_cb;
167 CallVoidMethod("start");
168 }
169
170 void MediaPlayerBridge::Pause() {
171 CallVoidMethod("pause");
172 }
173
174 void MediaPlayerBridge::Stop() {
175 CallVoidMethod("stop");
176 }
177
178 bool MediaPlayerBridge::IsPlaying() {
179 JNIEnv* env = AttachCurrentThread();
180 CHECK(env);
181
182 jmethodID method = GetMethodID(env,
183 j_media_player_class_,
184 "isPlaying",
185 "()Z"); 260 "()Z");
186 jint result = env->CallBooleanMethod(j_media_player_.obj(), method); 261 jboolean result = env->CallBooleanMethod(j_media_player_.obj(), method);
187 CheckException(env); 262 CheckException(env);
188 263
189 return result; 264 return result;
190 } 265 }
191 266
192 int MediaPlayerBridge::GetVideoWidth() { 267 int MediaPlayerBridge::GetVideoWidth() {
268 if (!prepared_)
269 return width_;
193 return CallIntMethod("getVideoWidth"); 270 return CallIntMethod("getVideoWidth");
194 } 271 }
195 272
196 int MediaPlayerBridge::GetVideoHeight() { 273 int MediaPlayerBridge::GetVideoHeight() {
274 if (!prepared_)
275 return height_;
197 return CallIntMethod("getVideoHeight"); 276 return CallIntMethod("getVideoHeight");
198 } 277 }
199 278
200 void MediaPlayerBridge::SeekTo(base::TimeDelta time, 279 void MediaPlayerBridge::SeekTo(base::TimeDelta time) {
201 const base::Closure& seek_complete_cb) { 280 // Record the time to seek when OnMediaPrepared() is called.
202 seek_complete_cb_ = seek_complete_cb; 281 pending_seek_ = time;
203 JNIEnv* env = AttachCurrentThread();
204 CHECK(env);
205 282
206 jmethodID method = GetMethodID(env, j_media_player_class_, "seekTo", "(I)V"); 283 if (j_media_player_.is_null())
207 DCHECK(method); 284 Prepare();
208 int time_msec = static_cast<int>(time.InMilliseconds()); 285 else if (prepared_)
209 DCHECK_EQ(time.InMilliseconds(), static_cast<int64>(time_msec)); 286 SeekInternal(time);
210 env->CallVoidMethod(j_media_player_.obj(),
211 method,
212 time_msec);
213 CheckException(env);
214 } 287 }
215 288
216 base::TimeDelta MediaPlayerBridge::GetCurrentTime() { 289 base::TimeDelta MediaPlayerBridge::GetCurrentTime() {
290 if (!prepared_)
291 return pending_seek_;
217 return base::TimeDelta::FromMilliseconds(CallIntMethod("getCurrentPosition")); 292 return base::TimeDelta::FromMilliseconds(CallIntMethod("getCurrentPosition"));
218 } 293 }
219 294
220 base::TimeDelta MediaPlayerBridge::GetDuration() { 295 base::TimeDelta MediaPlayerBridge::GetDuration() {
296 if (!prepared_)
297 return duration_;
221 return base::TimeDelta::FromMilliseconds(CallIntMethod("getDuration")); 298 return base::TimeDelta::FromMilliseconds(CallIntMethod("getDuration"));
222 } 299 }
223 300
224 void MediaPlayerBridge::Reset() { 301 void MediaPlayerBridge::Release() {
225 CallVoidMethod("reset"); 302 if (j_media_player_.is_null())
303 return;
304
305 time_update_timer_.Stop();
306 if (prepared_)
307 pending_seek_ = GetCurrentTime();
308 if (manager_)
309 manager_->ReleaseMediaResources(this);
310 prepared_ = false;
311 pending_play_ = false;
312 SetVideoSurface(NULL);
313 CallVoidMethod("release");
314 j_media_player_.Reset();
226 } 315 }
227 316
228 void MediaPlayerBridge::SetVolume(float left_volume, float right_volume) { 317 void MediaPlayerBridge::SetVolume(float left_volume, float right_volume) {
318 if (j_media_player_.is_null())
319 return;
320
229 JNIEnv* env = AttachCurrentThread(); 321 JNIEnv* env = AttachCurrentThread();
230 CHECK(env); 322 CHECK(env);
231 323
232 jmethodID method = GetMethodID(env, 324 jmethodID method = GetMethodID(env,
233 j_media_player_class_, 325 j_media_player_class_,
234 "setVolume", 326 "setVolume",
235 "(FF)V"); 327 "(FF)V");
236 DCHECK(method); 328 DCHECK(method);
237 env->CallVoidMethod(j_media_player_.obj(), method, 329 env->CallVoidMethod(j_media_player_.obj(), method,
238 left_volume, right_volume); 330 left_volume, right_volume);
239 CheckException(env); 331 CheckException(env);
240 } 332 }
241 333
242 void MediaPlayerBridge::SetStayAwakeWhilePlaying() { 334 void MediaPlayerBridge::DoTimeUpdate() {
335 base::TimeDelta current = GetCurrentTime();
336 time_update_cb_.Run(player_id_, current);
337 }
338
339 void MediaPlayerBridge::OnMediaError(int error_type) {
340 media_error_cb_.Run(player_id_, error_type);
341 }
342
343 void MediaPlayerBridge::OnVideoSizeChanged(int width, int height) {
344 width_ = width;
345 height_ = height_;
346 video_size_changed_cb_.Run(player_id_, width, height);
347 }
348
349 void MediaPlayerBridge::OnBufferingUpdate(int percent) {
350 buffering_update_cb_.Run(player_id_, percent);
351 }
352
353 void MediaPlayerBridge::OnPlaybackComplete() {
354 time_update_timer_.Stop();
355 playback_complete_cb_.Run(player_id_);
356 }
357
358 void MediaPlayerBridge::OnSeekComplete() {
359 seek_complete_cb_.Run(player_id_, GetCurrentTime());
360 }
361
362 void MediaPlayerBridge::OnMediaPrepared() {
363 if (j_media_player_.is_null())
364 return;
365
366 prepared_ = true;
367
368 base::TimeDelta dur = duration_;
369 duration_ = GetDuration();
370
371 if (duration_ != dur && 0 != dur.InMilliseconds()) {
372 // Scale the |pending_seek_| according to the new duration.
373 pending_seek_ = base::TimeDelta::FromSeconds(
374 pending_seek_.InSecondsF() * duration_.InSecondsF() / dur.InSecondsF());
375 }
376
377 // If media player was recovered from a saved state, consume all the pending
378 // events.
379 SeekInternal(pending_seek_);
380
381 if (pending_play_) {
382 StartInternal();
383 pending_play_ = false;
384 }
385
386 GetMetadata();
387
388 media_prepared_cb_.Run(player_id_, duration_);
389 }
390
391 void MediaPlayerBridge::GetMetadata() {
243 JNIEnv* env = AttachCurrentThread(); 392 JNIEnv* env = AttachCurrentThread();
244 CHECK(env); 393 CHECK(env);
245 394
246 jobject j_context = base::android::GetApplicationContext();
247 DCHECK(j_context);
248 jint j_mode = kAndroidFullWakeLock;
249 jmethodID method = GetMethodID(env, j_media_player_class_,
250 "setWakeMode", "(Landroid/content/Context;I)V");
251 env->CallVoidMethod(j_media_player_.obj(), method, j_context, j_mode);
252 CheckException(env);
253 }
254
255 void MediaPlayerBridge::OnMediaError(JNIEnv* /* env */,
256 jobject /* obj */,
257 jint error_type) {
258 media_error_cb_.Run(error_type);
259 }
260
261 void MediaPlayerBridge::OnMediaInfo(JNIEnv* /* env */,
262 jobject /* obj */,
263 jint info_type) {
264 media_info_cb_.Run(info_type);
265 }
266
267 void MediaPlayerBridge::OnVideoSizeChanged(JNIEnv* /* env */,
268 jobject /* obj */,
269 jint width,
270 jint height) {
271 video_size_changed_cb_.Run(width, height);
272 }
273
274 void MediaPlayerBridge::OnBufferingUpdate(JNIEnv* /* env */,
275 jobject /* obj */,
276 jint percent) {
277 buffering_update_cb_.Run(percent);
278 }
279
280 void MediaPlayerBridge::OnPlaybackComplete(JNIEnv* /* env */,
281 jobject /* obj */) {
282 playback_complete_cb_.Run();
283 }
284
285 void MediaPlayerBridge::OnSeekComplete(JNIEnv* /* env */,
286 jobject /* obj */) {
287 seek_complete_cb_.Run();
288 }
289
290 void MediaPlayerBridge::OnMediaPrepared(JNIEnv* /* env */,
291 jobject /* obj */) {
292 media_prepared_cb_.Run();
293 }
294
295 void MediaPlayerBridge::GetMetadata(bool* can_pause,
296 bool* can_seek_forward,
297 bool* can_seek_backward) {
298 JNIEnv* env = AttachCurrentThread();
299 CHECK(env);
300
301 jmethodID method = GetMethodID(env, 395 jmethodID method = GetMethodID(env,
302 j_media_player_class_, 396 j_media_player_class_,
303 "getMetadata", 397 "getMetadata",
304 "(ZZ)Landroid/media/Metadata;"); 398 "(ZZ)Landroid/media/Metadata;");
305 ScopedJavaLocalRef<jobject> j_metadata(env, 399 ScopedJavaLocalRef<jobject> j_metadata(env,
306 env->CallObjectMethod(j_media_player_.obj(), 400 env->CallObjectMethod(j_media_player_.obj(),
307 method, JNI_FALSE, JNI_FALSE)); 401 method, JNI_FALSE, JNI_FALSE));
308 CheckException(env); 402 CheckException(env);
309 if (j_metadata.is_null()) 403 if (j_metadata.is_null())
310 return; 404 return;
311 405
312 ScopedJavaLocalRef<jclass> cls(GetClass(env, "android/media/Metadata")); 406 ScopedJavaLocalRef<jclass> cls(GetClass(env, "android/media/Metadata"));
313 jmethodID get_boolean = GetMethodID(env, cls, "getBoolean", "(I)Z"); 407 jmethodID get_boolean = GetMethodID(env, cls, "getBoolean", "(I)Z");
314 *can_pause = env->CallBooleanMethod(j_metadata.obj(), 408 can_pause_ = env->CallBooleanMethod(j_metadata.obj(),
315 get_boolean, 409 get_boolean,
316 kPauseAvailable); 410 kPauseAvailable);
317 CheckException(env); 411 CheckException(env);
318 *can_seek_backward = env->CallBooleanMethod(j_metadata.obj(), 412 can_seek_forward_ = env->CallBooleanMethod(j_metadata.obj(),
413 get_boolean,
414 kSeekBackwardAvailable);
415 CheckException(env);
416 can_seek_backward_ = env->CallBooleanMethod(j_metadata.obj(),
319 get_boolean, 417 get_boolean,
320 kSeekBackwardAvailable); 418 kSeekForwardAvailable);
321 CheckException(env);
322 *can_seek_forward = env->CallBooleanMethod(j_metadata.obj(),
323 get_boolean,
324 kSeekForwardAvailable);
325 CheckException(env); 419 CheckException(env);
326 } 420 }
327 421
422 void MediaPlayerBridge::StartInternal() {
423 CallVoidMethod("start");
424 if (!time_update_timer_.IsRunning()) {
425 time_update_timer_.Start(
426 FROM_HERE,
427 base::TimeDelta::FromMilliseconds(kTimeUpdateInterval),
428 this, &MediaPlayerBridge::DoTimeUpdate);
429 }
430 }
431
432 void MediaPlayerBridge::PauseInternal() {
433 CallVoidMethod("pause");
434 time_update_timer_.Stop();
435 }
436
437 void MediaPlayerBridge::SeekInternal(base::TimeDelta time) {
438 JNIEnv* env = AttachCurrentThread();
439 CHECK(env);
440
441 jmethodID method = GetMethodID(env, j_media_player_class_, "seekTo", "(I)V");
442 DCHECK(method);
443 int time_msec = static_cast<int>(time.InMilliseconds());
444 DCHECK_EQ(time.InMilliseconds(), static_cast<int64>(time_msec));
445 env->CallVoidMethod(j_media_player_.obj(),
446 method,
447 time_msec);
448 CheckException(env);
449 }
450
328 // ---- JNI Helpers for repeated call patterns. ---- 451 // ---- JNI Helpers for repeated call patterns. ----
329 452
330 void MediaPlayerBridge::CallVoidMethod(std::string method_name) { 453 void MediaPlayerBridge::CallVoidMethod(std::string method_name) {
331 JNIEnv* env = AttachCurrentThread(); 454 JNIEnv* env = AttachCurrentThread();
332 CHECK(env); 455 CHECK(env);
333 456
334 jmethodID method = GetMethodID(env, 457 jmethodID method = GetMethodID(env,
335 j_media_player_class_, 458 j_media_player_class_,
336 method_name.c_str(), 459 method_name.c_str(),
337 "()V"); 460 "()V");
338 env->CallVoidMethod(j_media_player_.obj(), method); 461 env->CallVoidMethod(j_media_player_.obj(), method);
339 CheckException(env); 462 CheckException(env);
340 } 463 }
341 464
342 int MediaPlayerBridge::CallIntMethod(std::string method_name) { 465 int MediaPlayerBridge::CallIntMethod(std::string method_name) {
343 JNIEnv* env = AttachCurrentThread(); 466 JNIEnv* env = AttachCurrentThread();
344 CHECK(env); 467 CHECK(env);
345 468
346 jmethodID method = GetMethodID(env, 469 jmethodID method = GetMethodID(env,
347 j_media_player_class_, 470 j_media_player_class_,
348 method_name.c_str(), 471 method_name.c_str(),
349 "()I"); 472 "()I");
350 jint j_result = env->CallIntMethod(j_media_player_.obj(), method); 473 jint j_result = env->CallIntMethod(j_media_player_.obj(), method);
351 CheckException(env); 474 CheckException(env);
352 return j_result; 475 return j_result;
353 } 476 }
354 477
355 bool MediaPlayerBridge::RegisterMediaPlayerListener(JNIEnv* env) {
356 bool ret = RegisterNativesImpl(env);
357 DCHECK(g_MediaPlayerListener_clazz);
358 return ret;
359 }
360
361 } // namespace media 478 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698