Commit b4784025 authored by Andrei Pascovici's avatar Andrei Pascovici Committed by Commit Bot

Fix for internal bug below

Fixes an issue where the visibility change was not percolated to the
DialogOverlay, which prevented resuming DRM playback on certain cast systems
as described in the internal bug.

Bug=b:78571682
Test=made sure the repro steps actually work w. the CL

Change-Id: I7b2f06a5b4c4eb1fd4ffd32a587444e49d1ffcf8
Reviewed-on: https://chromium-review.googlesource.com/1204718
Commit-Queue: Andrei Pascovici <apascovici@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589164}
parent d48e1217
...@@ -71,7 +71,8 @@ DialogOverlayImpl::DialogOverlayImpl(const JavaParamRef<jobject>& obj, ...@@ -71,7 +71,8 @@ DialogOverlayImpl::DialogOverlayImpl(const JavaParamRef<jobject>& obj,
bool power_efficient) bool power_efficient)
: WebContentsObserver(web_contents), : WebContentsObserver(web_contents),
rfhi_(rfhi), rfhi_(rfhi),
power_efficient_(power_efficient) { power_efficient_(power_efficient),
observed_window_android_(false) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(rfhi_); DCHECK(rfhi_);
...@@ -105,9 +106,11 @@ void DialogOverlayImpl::CompleteInit(JNIEnv* env, ...@@ -105,9 +106,11 @@ void DialogOverlayImpl::CompleteInit(JNIEnv* env,
// Send the initial token, if there is one. The observer will notify us about // Send the initial token, if there is one. The observer will notify us about
// changes only. // changes only.
if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) { if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) {
RegisterWindowObserverIfNeeded(window);
ScopedJavaLocalRef<jobject> token = window->GetWindowToken(); ScopedJavaLocalRef<jobject> token = window->GetWindowToken();
if (!token.is_null()) if (!token.is_null()) {
Java_DialogOverlayImpl_onWindowToken(env, obj, token); Java_DialogOverlayImpl_onWindowToken(env, obj, token);
}
// else we will send one if we get a callback from ViewAndroid. // else we will send one if we get a callback from ViewAndroid.
} }
} }
...@@ -117,7 +120,7 @@ DialogOverlayImpl::~DialogOverlayImpl() { ...@@ -117,7 +120,7 @@ DialogOverlayImpl::~DialogOverlayImpl() {
} }
void DialogOverlayImpl::Stop() { void DialogOverlayImpl::Stop() {
UnregisterForTokensIfNeeded(); UnregisterCallbacksIfNeeded();
JNIEnv* env = AttachCurrentThread(); JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = obj_.get(env); ScopedJavaLocalRef<jobject> obj = obj_.get(env);
...@@ -129,7 +132,7 @@ void DialogOverlayImpl::Stop() { ...@@ -129,7 +132,7 @@ void DialogOverlayImpl::Stop() {
void DialogOverlayImpl::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { void DialogOverlayImpl::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
UnregisterForTokensIfNeeded(); UnregisterCallbacksIfNeeded();
// We delete soon since this might be part of an onDismissed callback. // We delete soon since this might be part of an onDismissed callback.
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
} }
...@@ -145,7 +148,7 @@ void DialogOverlayImpl::GetCompositorOffset( ...@@ -145,7 +148,7 @@ void DialogOverlayImpl::GetCompositorOffset(
point.y()); point.y());
} }
void DialogOverlayImpl::UnregisterForTokensIfNeeded() { void DialogOverlayImpl::UnregisterCallbacksIfNeeded() {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!rfhi_) if (!rfhi_)
...@@ -158,6 +161,12 @@ void DialogOverlayImpl::UnregisterForTokensIfNeeded() { ...@@ -158,6 +161,12 @@ void DialogOverlayImpl::UnregisterForTokensIfNeeded() {
if (delegate) if (delegate)
delegate->SetOverlayMode(false); delegate->SetOverlayMode(false);
if (observed_window_android_) {
auto* window_android = web_contents()->GetNativeView()->GetWindowAndroid();
if (window_android)
window_android->RemoveObserver(this);
observed_window_android_ = false;
}
web_contents()->GetNativeView()->RemoveObserver(this); web_contents()->GetNativeView()->RemoveObserver(this);
rfhi_ = nullptr; rfhi_ = nullptr;
} }
...@@ -187,6 +196,11 @@ void DialogOverlayImpl::OnVisibilityChanged(content::Visibility visibility) { ...@@ -187,6 +196,11 @@ void DialogOverlayImpl::OnVisibilityChanged(content::Visibility visibility) {
Stop(); Stop();
} }
void DialogOverlayImpl::OnRootWindowVisibilityChanged(bool visible) {
if (!visible)
Stop();
}
void DialogOverlayImpl::WebContentsDestroyed() { void DialogOverlayImpl::WebContentsDestroyed() {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
Stop(); Stop();
...@@ -213,9 +227,10 @@ void DialogOverlayImpl::OnAttachedToWindow() { ...@@ -213,9 +227,10 @@ void DialogOverlayImpl::OnAttachedToWindow() {
ScopedJavaLocalRef<jobject> token; ScopedJavaLocalRef<jobject> token;
if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) {
RegisterWindowObserverIfNeeded(window);
token = window->GetWindowToken(); token = window->GetWindowToken();
}
ScopedJavaLocalRef<jobject> obj = obj_.get(env); ScopedJavaLocalRef<jobject> obj = obj_.get(env);
if (!obj.is_null()) if (!obj.is_null())
Java_DialogOverlayImpl_onWindowToken(env, obj, token); Java_DialogOverlayImpl_onWindowToken(env, obj, token);
...@@ -228,6 +243,14 @@ void DialogOverlayImpl::OnDetachedFromWindow() { ...@@ -228,6 +243,14 @@ void DialogOverlayImpl::OnDetachedFromWindow() {
Java_DialogOverlayImpl_onWindowToken(env, obj, nullptr); Java_DialogOverlayImpl_onWindowToken(env, obj, nullptr);
} }
void DialogOverlayImpl::RegisterWindowObserverIfNeeded(
ui::WindowAndroid* window) {
if (!observed_window_android_) {
observed_window_android_ = true;
window->AddObserver(this);
}
}
static jint JNI_DialogOverlayImpl_RegisterSurface( static jint JNI_DialogOverlayImpl_RegisterSurface(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller, const base::android::JavaParamRef<jclass>& jcaller,
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "ui/android/view_android_observer.h" #include "ui/android/view_android_observer.h"
#include "ui/android/window_android.h"
#include "ui/android/window_android_observer.h"
namespace content { namespace content {
...@@ -20,6 +22,7 @@ namespace content { ...@@ -20,6 +22,7 @@ namespace content {
// detached from a WindowAndroid, we get the Android window token and notify the // detached from a WindowAndroid, we get the Android window token and notify the
// java side. // java side.
class DialogOverlayImpl : public ui::ViewAndroidObserver, class DialogOverlayImpl : public ui::ViewAndroidObserver,
public ui::WindowAndroidObserver,
public WebContentsObserver { public WebContentsObserver {
public: public:
// This may not call back into |obj| directly, but must post. This is because // This may not call back into |obj| directly, but must post. This is because
...@@ -59,12 +62,21 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver, ...@@ -59,12 +62,21 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver,
void RenderFrameHostChanged(RenderFrameHost* old_host, void RenderFrameHostChanged(RenderFrameHost* old_host,
RenderFrameHost* new_host) override; RenderFrameHost* new_host) override;
// Unregister for tokens if we're registered. // Unregister callbacks if previously registered.
void UnregisterForTokensIfNeeded(); void UnregisterCallbacksIfNeeded();
// WindowAndroidObserver
void OnRootWindowVisibilityChanged(bool visible) override;
void OnCompositingDidCommit() override {}
void OnAttachCompositor() override {}
void OnDetachCompositor() override {}
void OnActivityStopped() override {}
void OnActivityStarted() override {}
private: private:
// Signals the overlay should be cleaned up and no longer used. // Signals the overlay should be cleaned up and no longer used.
void Stop(); void Stop();
void RegisterWindowObserverIfNeeded(ui::WindowAndroid* window);
// Java object that owns us. // Java object that owns us.
JavaObjectWeakGlobalRef obj_; JavaObjectWeakGlobalRef obj_;
...@@ -74,6 +86,9 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver, ...@@ -74,6 +86,9 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver,
// Do we care about power efficiency? // Do we care about power efficiency?
bool power_efficient_; bool power_efficient_;
// Whether we added ourselves as an observer through WindowAndroid.
bool observed_window_android_;
}; };
} // namespace content } // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment