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

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

Powered by Google App Engine
This is Rietveld 408576698