The previous implementation is not correct, it depended on the Fullscreen video class, but the PowerSaveBlocker could be used for embedding video or the use case which isn't related to the video at all.
This patch adds new API to PowerSaveBlocker.
BUG=247892
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=212022
Review URL: https://chromiumcodereview.appspot.com/17175009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212536 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index b914a9a2..9ee8f24a 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -25,6 +25,7 @@
#include "content/browser/android/tracing_intent_handler.h"
#include "content/browser/android/web_contents_observer_android.h"
#include "content/browser/geolocation/location_api_adapter_android.h"
+#include "content/browser/power_save_blocker_android.h"
#include "content/browser/renderer_host/ime_adapter_android.h"
#include "content/browser/renderer_host/java/java_bound_object.h"
#include "content/browser/speech/speech_recognizer_impl_android.h"
@@ -53,6 +54,7 @@
{ "MediaResourceGetterImpl",
content::MediaResourceGetterImpl::RegisterMediaResourceGetter },
{ "LoadUrlParams", content::RegisterLoadUrlParams },
+ { "PowerSaveBlock", content::RegisterPowerSaveBlocker },
{ "RegisterImeAdapter", content::RegisterImeAdapter },
{ "SpeechRecognizerImplAndroid",
content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer },
diff --git a/content/browser/android/content_video_view.cc b/content/browser/android/content_video_view.cc
index 366182e..144ac01 100644
--- a/content/browser/android/content_video_view.cc
+++ b/content/browser/android/content_video_view.cc
@@ -65,12 +65,6 @@
Java_ContentVideoView_openVideo(env, content_video_view.obj());
}
-// static
-void ContentVideoView::KeepScreenOn(bool screen_on) {
- Java_ContentVideoView_keepScreenOnContentVideoView(AttachCurrentThread(),
- screen_on);
-}
-
void ContentVideoView::OnMediaPlayerError(int error_type) {
JNIEnv *env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
diff --git a/content/browser/power_save_blocker_android.cc b/content/browser/power_save_blocker_android.cc
index 23580497..45dda181 100644
--- a/content/browser/power_save_blocker_android.cc
+++ b/content/browser/power_save_blocker_android.cc
@@ -2,18 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/power_save_blocker_impl.h"
+#include "content/browser/power_save_blocker_android.h"
+#include "base/android/jni_android.h"
#include "base/logging.h"
-#include "content/browser/android/content_video_view.h"
+#include "content/browser/power_save_blocker_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "jni/PowerSaveBlocker_jni.h"
+#include "ui/android/window_android.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ScopedJavaLocalRef;
namespace content {
class PowerSaveBlockerImpl::Delegate
: public base::RefCountedThreadSafe<PowerSaveBlockerImpl::Delegate> {
public:
- explicit Delegate(PowerSaveBlockerType type) : type_(type) {}
+ explicit Delegate(gfx::NativeWindow native_window) {
+ j_window_android_ = JavaObjectWeakGlobalRef(AttachCurrentThread(),
+ static_cast<ui::WindowAndroid*>(native_window)->GetJavaObject().obj());
+ }
// Does the actual work to apply or remove the desired power save block.
void ApplyBlock();
@@ -23,49 +32,51 @@
friend class base::RefCountedThreadSafe<Delegate>;
~Delegate() {}
- // The counter of requests from clients for type
- // kPowerSaveBlockPreventDisplaySleep.
- static int blocker_count_;
- const PowerSaveBlockerType type_;
+ JavaObjectWeakGlobalRef j_window_android_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
-int PowerSaveBlockerImpl::Delegate::blocker_count_ = 0;
-
void PowerSaveBlockerImpl::Delegate::ApplyBlock() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (type_ != kPowerSaveBlockPreventDisplaySleep)
- return;
-
- if (blocker_count_ == 0)
- ContentVideoView::KeepScreenOn(true);
- ++blocker_count_;
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> j_object = j_window_android_.get(env);
+ if (j_object.obj())
+ Java_PowerSaveBlocker_applyBlock(env, j_object.obj());
}
void PowerSaveBlockerImpl::Delegate::RemoveBlock() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (type_ != kPowerSaveBlockPreventDisplaySleep)
- return;
-
- --blocker_count_;
- if (blocker_count_ == 0)
- ContentVideoView::KeepScreenOn(false);
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> j_object = j_window_android_.get(env);
+ if (j_object.obj())
+ Java_PowerSaveBlocker_removeBlock(env, j_object.obj());
}
PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type,
- const std::string& reason)
- : delegate_(new Delegate(type)) {
+ const std::string& reason) {
+ // Don't support kPowerSaveBlockPreventAppSuspension
+}
+
+PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
+ if (delegate_) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&Delegate::RemoveBlock, delegate_));
+ }
+}
+
+void PowerSaveBlockerImpl::InitDisplaySleepBlocker(
+ gfx::NativeWindow native_window) {
+ delegate_ = new Delegate(native_window);
// This may be called on any thread.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&Delegate::ApplyBlock, delegate_));
}
-PowerSaveBlockerImpl::~PowerSaveBlockerImpl() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&Delegate::RemoveBlock, delegate_));
+bool RegisterPowerSaveBlocker(JNIEnv* env) {
+ return RegisterNativesImpl(env);
}
} // namespace content
diff --git a/content/browser/power_save_blocker_android.h b/content/browser/power_save_blocker_android.h
new file mode 100644
index 0000000..1df7d69
--- /dev/null
+++ b/content/browser/power_save_blocker_android.h
@@ -0,0 +1,11 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <jni.h>
+
+namespace content {
+
+bool RegisterPowerSaveBlocker(JNIEnv* env);
+
+} // namespace content
diff --git a/content/browser/power_save_blocker_impl.h b/content/browser/power_save_blocker_impl.h
index fd0e63ad..c3a105d4 100644
--- a/content/browser/power_save_blocker_impl.h
+++ b/content/browser/power_save_blocker_impl.h
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted.h"
#include "content/public/browser/power_save_blocker.h"
+#include "ui/gfx/native_widget_types.h"
namespace content {
@@ -15,6 +16,14 @@
PowerSaveBlockerImpl(PowerSaveBlockerType type, const std::string& reason);
virtual ~PowerSaveBlockerImpl();
+#if defined(OS_ANDROID)
+ // In Android platform, the |native_window| is needed to create the
+ // kPowerSaveBlockPreventDisplaySleep type of PowerSaveBlocker
+ // so the blocker could be removed by platform if the window isn't in the
+ // foreground.
+ void InitDisplaySleepBlocker(gfx::NativeWindow native_window);
+#endif
+
private:
class Delegate;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 9913fd9..cc08df57 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -50,7 +50,6 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
-#include "content/public/browser/power_save_blocker.h"
#include "content/public/browser/render_view_host_observer.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/bindings_policy.h"
@@ -200,9 +199,7 @@
FOR_EACH_OBSERVER(
RenderViewHostObserver, observers_, RenderViewHostDestruction());
- ClearPowerSaveBlockers();
-
- GetDelegate()->RenderViewDeleted(this);
+ GetDelegate()->RenderViewDeleted(this);
// Be sure to clean up any leftover state from cross-site requests.
CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest(
@@ -987,7 +984,6 @@
OnSelectionBoundsChanged)
IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
- IPC_MESSAGE_HANDLER(ViewHostMsg_MediaNotification, OnMediaNotification)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowSnapshot, OnGetWindowSnapshot)
IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission,
OnRequestDesktopNotificationPermission)
@@ -1127,7 +1123,6 @@
static_cast<base::TerminationStatus>(status);
// Reset state.
- ClearPowerSaveBlockers();
main_frame_id_ = -1;
// Our base class RenderWidgetHost needs to reset some stuff.
@@ -1946,33 +1941,6 @@
}
}
-void RenderViewHostImpl::OnMediaNotification(int64 player_cookie,
- bool has_video,
- bool has_audio,
- bool is_playing) {
- // Chrome OS does its own detection of audio and video.
-#if !defined(OS_CHROMEOS)
- if (is_playing) {
- scoped_ptr<PowerSaveBlocker> blocker;
- if (has_video) {
- blocker = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
- "Playing video");
- } else if (has_audio) {
- blocker = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
- "Playing audio");
- }
-
- if (blocker)
- power_save_blockers_[player_cookie] = blocker.release();
- } else {
- delete power_save_blockers_[player_cookie];
- power_save_blockers_.erase(player_cookie);
- }
-#endif
-}
-
void RenderViewHostImpl::OnRequestDesktopNotificationPermission(
const GURL& source_origin, int callback_context) {
GetContentClient()->browser()->RequestDesktopNotificationPermission(
@@ -2074,10 +2042,6 @@
has_timed_out_on_unload_ = false;
}
-void RenderViewHostImpl::ClearPowerSaveBlockers() {
- STLDeleteValues(&power_save_blockers_);
-}
-
bool RenderViewHostImpl::CanAccessFilesOfPageState(
const PageState& state) const {
ChildProcessSecurityPolicyImpl* policy =
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index d264324..3ab434f 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -63,7 +63,6 @@
class ChildProcessSecurityPolicyImpl;
class PageState;
-class PowerSaveBlocker;
class RenderFrameHostImpl;
class RenderViewHostObserver;
class RenderWidgetHostDelegate;
@@ -567,10 +566,6 @@
const std::vector<AccessibilityHostMsg_NotificationParams>& params);
void OnScriptEvalResponse(int id, const base::ListValue& result);
void OnDidZoomURL(double zoom_level, bool remember, const GURL& url);
- void OnMediaNotification(int64 player_cookie,
- bool has_video,
- bool has_audio,
- bool is_playing);
void OnRequestDesktopNotificationPermission(const GURL& origin,
int callback_id);
void OnShowDesktopNotification(
@@ -594,8 +589,6 @@
// and clears any waiting state that is no longer relevant.
void SetSwappedOut(bool is_swapped_out);
- void ClearPowerSaveBlockers();
-
bool CanAccessFilesOfPageState(const PageState& state) const;
// This is an RenderFrameHost object associated with the top-level frame in
@@ -697,11 +690,6 @@
// The termination status of the last render view that terminated.
base::TerminationStatus render_view_termination_status_;
- // Holds PowerSaveBlockers for the media players in use. Key is the
- // player_cookie passed to OnMediaNotification, value is the PowerSaveBlocker.
- typedef std::map<int64, PowerSaveBlocker*> PowerSaveBlockerMap;
- PowerSaveBlockerMap power_save_blockers_;
-
// A list of observers that filter messages. Weak references.
ObserverList<RenderViewHostObserver> observers_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4cd9375d..53fb4bc5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -32,6 +32,7 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/power_save_blocker_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -359,6 +360,8 @@
WebContentsImpl::~WebContentsImpl() {
is_being_destroyed_ = true;
+ ClearAllPowerSaveBlockers();
+
for (std::set<RenderWidgetHostImpl*>::iterator iter =
created_widgets_.begin(); iter != created_widgets_.end(); ++iter) {
(*iter)->DetachDelegate();
@@ -718,6 +721,7 @@
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_FrameAttached, OnFrameAttached)
IPC_MESSAGE_HANDLER(ViewHostMsg_FrameDetached, OnFrameDetached)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_MediaNotification, OnMediaNotification)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
message_source_ = NULL;
@@ -2579,6 +2583,38 @@
parent->RemoveChild(frame_id);
}
+void WebContentsImpl::OnMediaNotification(int64 player_cookie,
+ bool has_video,
+ bool has_audio,
+ bool is_playing) {
+ // Chrome OS does its own detection of audio and video.
+#if !defined(OS_CHROMEOS)
+ if (is_playing) {
+ scoped_ptr<PowerSaveBlocker> blocker;
+ if (has_video) {
+ blocker = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
+ "Playing video");
+#if defined(OS_ANDROID)
+ static_cast<PowerSaveBlockerImpl*>(blocker.get())->
+ InitDisplaySleepBlocker(GetView()->GetTopLevelNativeWindow());
+#endif
+ } else if (has_audio) {
+ blocker = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
+ "Playing audio");
+ }
+
+ if (blocker)
+ power_save_blockers_[message_source_][player_cookie] = blocker.release();
+ } else {
+ delete power_save_blockers_[message_source_][player_cookie];
+ power_save_blockers_[message_source_].erase(player_cookie);
+ }
+#endif // !defined(OS_CHROMEOS)
+}
+
+
void WebContentsImpl::DidChangeVisibleSSLState() {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidChangeVisibleSSLState());
@@ -2868,6 +2904,7 @@
return;
}
+ ClearPowerSaveBlockers(rvh);
SetIsLoading(false, NULL);
NotifyDisconnected();
SetIsCrashed(status, error_code);
@@ -2879,6 +2916,7 @@
}
void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
+ ClearPowerSaveBlockers(rvh);
render_manager_.RenderViewDeleted(rvh);
FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
}
@@ -3685,4 +3723,17 @@
browser_plugin::kBrowserPluginGuestManagerKeyName));
}
+void WebContentsImpl::ClearPowerSaveBlockers(
+ RenderViewHost* render_view_host) {
+ STLDeleteValues(&power_save_blockers_[render_view_host]);
+ power_save_blockers_.erase(render_view_host);
+}
+
+void WebContentsImpl::ClearAllPowerSaveBlockers() {
+ for (PowerSaveBlockerMap::iterator i(power_save_blockers_.begin());
+ i != power_save_blockers_.end(); ++i)
+ STLDeleteValues(&power_save_blockers_[i->first]);
+ power_save_blockers_.clear();
+}
+
} // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index b5d1eb0c..645923664 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -47,6 +47,7 @@
class InterstitialPageImpl;
class JavaBridgeDispatcherHostManager;
class JavaScriptDialogManager;
+class PowerSaveBlocker;
class RenderViewHost;
class RenderViewHostDelegateView;
class RenderViewHostImpl;
@@ -625,6 +626,11 @@
const std::string& frame_name);
void OnFrameDetached(int64 parent_frame_id, int64 frame_id);
+ void OnMediaNotification(int64 player_cookie,
+ bool has_video,
+ bool has_audio,
+ bool is_playing);
+
// Changes the IsLoading state and notifies delegate as needed
// |details| is used to provide details on the load that just finished
// (but can be null if not applicable). Can be overridden.
@@ -742,6 +748,12 @@
// Removes browser plugin embedder if there is one.
void RemoveBrowserPluginEmbedder();
+ // Clear |render_view_host|'s PowerSaveBlockers.
+ void ClearPowerSaveBlockers(RenderViewHost* render_view_host);
+
+ // Clear all PowerSaveBlockers, leave power_save_blocker_ empty.
+ void ClearAllPowerSaveBlockers();
+
// Data for core operation ---------------------------------------------------
// Delegate for notifying our owner about stuff. Not owned by us.
@@ -787,6 +799,13 @@
// Helper classes ------------------------------------------------------------
+ // Maps the RenderViewHost to its media_player_cookie and PowerSaveBlocker
+ // pairs. Key is the RenderViewHost, value is the map which maps player_cookie
+ // on to PowerSaveBlocker.
+ typedef std::map<RenderViewHost*, std::map<int64, PowerSaveBlocker*> >
+ PowerSaveBlockerMap;
+ PowerSaveBlockerMap power_save_blockers_;
+
// Manages creation and swapping of render views.
RenderViewHostManager render_manager_;