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

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

Powered by Google App Engine
This is Rietveld 408576698