Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/media/session/media_session_android.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include "content/browser/media/session/media_session_impl.h" | |
| 9 #include "content/browser/web_contents/web_contents_android.h" | |
| 10 #include "content/browser/web_contents/web_contents_impl.h" | |
| 11 #include "content/common/android/media_metadata_android.h" | |
| 12 #include "content/public/browser/media_session.h" | |
| 13 #include "jni/MediaSessionImpl_jni.h" | |
| 14 | |
| 15 namespace content { | |
| 16 | |
| 17 using base::android::JavaParamRef; | |
| 18 | |
| 19 struct MediaSessionAndroid::JavaObjectGetter { | |
| 20 static const JavaObjectWeakGlobalRef& GetJavaObject( | |
| 21 MediaSessionAndroid* session_android) { | |
| 22 return session_android->j_media_session_; | |
| 23 } | |
| 24 }; | |
| 25 | |
| 26 MediaSessionAndroid::MediaSessionAndroid(MediaSessionImpl* session) | |
| 27 : MediaSessionObserver(session) { | |
| 28 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 29 base::android::ScopedJavaLocalRef<jobject> j_media_session = | |
| 30 Java_MediaSessionImpl_create(env, reinterpret_cast<intptr_t>(this)); | |
| 31 j_media_session_ = JavaObjectWeakGlobalRef(env, j_media_session); | |
| 32 | |
| 33 WebContentsAndroid* contents_android = GetWebContentsAndroid(); | |
| 34 if (contents_android) | |
| 35 contents_android->SetMediaSession(j_media_session); | |
| 36 } | |
| 37 | |
| 38 MediaSessionAndroid::~MediaSessionAndroid() { | |
| 39 // MediaSessionDestroyed() should have already been called. | |
| 40 DCHECK(j_media_session_.is_empty()); | |
| 41 } | |
| 42 | |
| 43 // static | |
| 44 bool MediaSessionAndroid::Register(JNIEnv* env) { | |
| 45 return RegisterNativesImpl(env); | |
| 46 } | |
| 47 | |
| 48 // static | |
| 49 base::android::ScopedJavaLocalRef<jobject> GetMediaSessionFromWebContents( | |
| 50 JNIEnv* env, | |
| 51 const JavaParamRef<jclass>& clazz, | |
| 52 const JavaParamRef<jobject>& j_contents_android) { | |
| 53 WebContents* contents = WebContents::FromJavaWebContents(j_contents_android); | |
| 54 if (!contents) | |
| 55 return base::android::ScopedJavaLocalRef<jobject>(); | |
| 56 | |
| 57 MediaSessionImpl* session = MediaSessionImpl::Get(contents); | |
| 58 DCHECK(session); | |
| 59 return MediaSessionAndroid::JavaObjectGetter::GetJavaObject( | |
| 60 session->session_android()) | |
| 61 .get(env); | |
| 62 } | |
| 63 | |
| 64 void MediaSessionAndroid::MediaSessionDestroyed() { | |
| 65 if (j_media_session_.is_empty()) | |
| 66 return; | |
| 67 | |
| 68 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 69 // The Java object will tear down after this call. | |
| 70 Java_MediaSessionImpl_mediaSessionDestroyed(env, j_media_session_.get(env)); | |
| 71 j_media_session_.reset(); | |
| 72 | |
| 73 WebContentsAndroid* contents_android = GetWebContentsAndroid(); | |
| 74 if (contents_android) | |
| 75 contents_android->SetMediaSession(nullptr); | |
| 76 } | |
| 77 | |
| 78 void MediaSessionAndroid::MediaSessionStateChanged(bool is_controllable, | |
| 79 bool is_suspended) { | |
| 80 if (j_media_session_.is_empty()) | |
|
boliu
2016/10/31 22:44:02
in theory, this check is not safe, there is no gua
Zhiqiang Zhang (Slow)
2016/10/31 23:30:29
Yes, you mentioned this before and I lost it after
| |
| 81 return; | |
| 82 | |
| 83 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 84 Java_MediaSessionImpl_mediaSessionStateChanged(env, j_media_session_.get(env), | |
| 85 is_controllable, is_suspended); | |
| 86 } | |
| 87 | |
| 88 void MediaSessionAndroid::MediaSessionMetadataChanged( | |
| 89 const base::Optional<MediaMetadata>& metadata) { | |
| 90 if (j_media_session_.is_empty()) | |
| 91 return; | |
| 92 | |
| 93 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 94 | |
| 95 // Avoid translating metadata through JNI if there is no Java observer. | |
| 96 if (!Java_MediaSessionImpl_hasObservers(env, j_media_session_.get(env))) | |
| 97 return; | |
| 98 | |
| 99 base::android::ScopedJavaLocalRef<jobject> j_metadata; | |
| 100 if (metadata.has_value()) | |
| 101 j_metadata = MediaMetadataAndroid::CreateJavaObject(env, metadata.value()); | |
| 102 Java_MediaSessionImpl_mediaSessionMetadataChanged( | |
| 103 env, j_media_session_.get(env), j_metadata); | |
| 104 } | |
| 105 | |
| 106 void MediaSessionAndroid::Resume( | |
| 107 JNIEnv* env, | |
| 108 const base::android::JavaParamRef<jobject>& j_obj) { | |
| 109 DCHECK(media_session()); | |
| 110 media_session()->Resume(MediaSession::SuspendType::UI); | |
| 111 } | |
| 112 | |
| 113 void MediaSessionAndroid::Suspend( | |
| 114 JNIEnv* env, | |
| 115 const base::android::JavaParamRef<jobject>& j_obj) { | |
| 116 DCHECK(media_session()); | |
| 117 media_session()->Suspend(MediaSession::SuspendType::UI); | |
| 118 } | |
| 119 | |
| 120 void MediaSessionAndroid::Stop( | |
| 121 JNIEnv* env, | |
| 122 const base::android::JavaParamRef<jobject>& j_obj) { | |
| 123 DCHECK(media_session()); | |
| 124 media_session()->Stop(MediaSession::SuspendType::UI); | |
| 125 } | |
| 126 | |
| 127 WebContentsAndroid* MediaSessionAndroid::GetWebContentsAndroid() { | |
| 128 MediaSessionImpl* session = static_cast<MediaSessionImpl*>(media_session()); | |
| 129 if (!session) | |
| 130 return nullptr; | |
| 131 WebContentsImpl* contents = | |
| 132 static_cast<WebContentsImpl*>(session->web_contents()); | |
| 133 if (!contents) | |
| 134 return nullptr; | |
| 135 return contents->GetWebContentsAndroid(); | |
| 136 } | |
| 137 | |
| 138 } // namespace content | |
| OLD | NEW |