Skip to content

Commit

Permalink
Upstream support for WebKit shared timer toggling.
Browse files Browse the repository at this point in the history
This is part of Chrome for Android upstreaming.

These changes are used on the Java app side to suspend webkit timers in all
renderers when activity is paused and resume timers when activity is resumed.

This reduces javascript execution when the app is in the background, causing
lesser CPU and network usage. It doesn't stop javascript altogether because if
the page JS is constantly running without relying on timers/events then it
continues to run (but that is quite rare).


Review URL: https://chromiumcodereview.appspot.com/10690023

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147438 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
pliard@chromium.org committed Jul 19, 2012
1 parent 8220e5d commit a1a7ff3
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 9 deletions.
1 change: 1 addition & 0 deletions base/android/jni_generator/jni_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def JavaParamToJni(param):
'PasswordListObserver'),
'Lorg/chromium/base/SystemMessageHandler',
'Lorg/chromium/chrome/browser/JSModalDialog',
'Lorg/chromium/chrome/browser/ProcessUtils',
'Lorg/chromium/chrome/browser/SelectFileDialog',
'Lorg/chromium/content/browser/ContentVideoView',
'Lorg/chromium/content/browser/ContentViewClient',
Expand Down
1 change: 1 addition & 0 deletions chrome/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include_rules = [
"+ash",
"+crypto",
"+gpu",
"+jni",
"+native_client",
"+net",
"+printing",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2012 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.

package org.chromium.chrome.browser;

/**
* A set of utility methods related to the various Chrome processes.
*/
public class ProcessUtils {
// To prevent this class from being instantiated.
private ProcessUtils() {
}

/**
* Suspends Webkit timers in all renderers.
*
* @param suspend true if timers should be suspended.
*/
public static void toggleWebKitSharedTimers(boolean suspend) {
nativeToggleWebKitSharedTimers(suspend);
}

private static native void nativeToggleWebKitSharedTimers(boolean suspend);
}
60 changes: 60 additions & 0 deletions chrome/browser/android/process_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2012 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 "chrome/browser/android/process_utils.h"

#include <vector>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/render_process_host.h"
#include "jni/process_utils_jni.h"

namespace {

// Only accessed from the JNI thread by ToggleWebKitSharedTimers() which is
// implemented below.
base::LazyInstance<std::vector<int /* process id */> > g_suspended_processes =
LAZY_INSTANCE_INITIALIZER;

// Suspends timers in all current render processes.
void SuspendWebKitSharedTimers(std::vector<int>* suspended_processes) {
for (content::RenderProcessHost::iterator i(
content::RenderProcessHost::AllHostsIterator());
!i.IsAtEnd(); i.Advance()) {
content::RenderProcessHost* host = i.GetCurrentValue();
suspended_processes->push_back(host->GetID());
host->Send(new ChromeViewMsg_ToggleWebKitSharedTimer(true));
}
}

void ResumeWebkitSharedTimers(const std::vector<int>& suspended_processes) {
for (std::vector<int>::const_iterator it = suspended_processes.begin();
it != suspended_processes.end(); ++it) {
content::RenderProcessHost* host = content::RenderProcessHost::FromID(*it);
if (host)
host->Send(new ChromeViewMsg_ToggleWebKitSharedTimer(false));
}
}

} // namespace

static void ToggleWebKitSharedTimers(JNIEnv* env,
jclass obj,
jboolean suspend) {
std::vector<int>* suspended_processes = &g_suspended_processes.Get();
if (suspend) {
DCHECK(suspended_processes->empty());
SuspendWebKitSharedTimers(suspended_processes);
} else {
ResumeWebkitSharedTimers(*suspended_processes);
suspended_processes->clear();
}
}

// TODO(pliard): http://crbug.com/137674
bool RegisterProcessUtils(JNIEnv* env) {
return RegisterNativesImpl(env);
}
12 changes: 12 additions & 0 deletions chrome/browser/android/process_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2012 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.

#ifndef CHROME_BROWSER_ANDROID_PROCESS_UTILS_H_
#define CHROME_BROWSER_ANDROID_PROCESS_UTILS_H_

#include <jni.h>

bool RegisterProcessUtils(JNIEnv* env);

#endif // CHROME_BROWSER_ANDROID_PROCESS_UTILS_H_
25 changes: 25 additions & 0 deletions chrome/chrome_browser.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
'browser/accessibility/invert_bubble_prefs.h',
'browser/android/chrome_startup_flags.cc',
'browser/android/chrome_startup_flags.h',
'browser/android/process_utils.cc',
'browser/android/process_utils.h',
'browser/alternate_nav_url_fetcher.cc',
'browser/alternate_nav_url_fetcher.h',
'browser/app_controller_mac.h',
Expand Down Expand Up @@ -4856,6 +4858,9 @@
],
}],
['OS=="android"', {
'dependencies': [
'chrome_browser_jni_headers',
],
'sources': [
'browser/sync/glue/synced_window_delegate_registry.cc',
'browser/sync/glue/synced_window_delegate_registry.h',
Expand Down Expand Up @@ -5443,4 +5448,24 @@
'includes': [ '../build/protoc.gypi' ]
},
],
'conditions': [
['OS == "android"', {
'targets': [
{
'target_name': 'chrome_browser_jni_headers',
'type': 'none',
'variables': {
'java_sources': [
'android/java/src/org/chromium/chrome/browser/ProcessUtils.java',
],
'jni_headers': [
'<(SHARED_INTERMEDIATE_DIR)/chrome/jni/process_utils_jni.h',
],
},
'includes': [ '../build/jni_generator.gypi' ],
},
],
},
],
],
}
4 changes: 4 additions & 0 deletions chrome/common/render_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ IPC_MESSAGE_ROUTED0(ChromeViewMsg_GetFPS)
// Tells the view it is displaying an interstitial page.
IPC_MESSAGE_ROUTED0(ChromeViewMsg_SetAsInterstitial)

// Tells the renderer to suspend/resume the webkit timers.
IPC_MESSAGE_CONTROL1(ChromeViewMsg_ToggleWebKitSharedTimer,
bool /* suspend */)

//-----------------------------------------------------------------------------
// Misc messages
// These are messages sent from the renderer to the browser process.
Expand Down
6 changes: 6 additions & 0 deletions chrome/renderer/chrome_render_process_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(ChromeViewMsg_PurgeMemory, OnPurgeMemory)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
OnSetContentSettingRules)
IPC_MESSAGE_HANDLER(ChromeViewMsg_ToggleWebKitSharedTimer,
OnToggleWebKitSharedTimer)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
Expand Down Expand Up @@ -320,6 +322,10 @@ void ChromeRenderProcessObserver::OnGetV8HeapStats() {
heap_stats.total_heap_size(), heap_stats.used_heap_size()));
}

void ChromeRenderProcessObserver::OnToggleWebKitSharedTimer(bool suspend) {
RenderThread::Get()->ToggleWebKitSharedTimer(suspend);
}

void ChromeRenderProcessObserver::OnPurgeMemory() {
RenderThread::Get()->EnsureWebKitInitialized();

Expand Down
1 change: 1 addition & 0 deletions chrome/renderer/chrome_render_process_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver {
void OnWriteTcmallocHeapProfile(const FilePath::StringType& filename);
void OnGetV8HeapStats();
void OnPurgeMemory();
void OnToggleWebKitSharedTimer(bool suspend);

static bool is_incognito_process_;
scoped_ptr<content::ResourceDispatcherDelegate> resource_delegate_;
Expand Down
3 changes: 3 additions & 0 deletions content/public/renderer/render_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class CONTENT_EXPORT RenderThread : public IPC::Sender {
virtual void SetIdleNotificationDelayInMs(
int64 idle_notification_delay_in_ms) = 0;

// Suspend/resume the webkit timer for this renderer.
virtual void ToggleWebKitSharedTimer(bool suspend) = 0;

virtual void UpdateHistograms(int sequence_number) = 0;

#if defined(OS_WIN)
Expand Down
3 changes: 2 additions & 1 deletion content/public/test/mock_render_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ class MockRenderThread : public RenderThread {
virtual int64 GetIdleNotificationDelayInMs() const OVERRIDE;
virtual void SetIdleNotificationDelayInMs(
int64 idle_notification_delay_in_ms) OVERRIDE;
virtual void ToggleWebKitSharedTimer(bool suspend) OVERRIDE;
virtual void UpdateHistograms(int sequence_number) OVERRIDE;
#if defined(OS_WIN)
virtual void PreCacheFont(const LOGFONT& log_font) OVERRIDE;
virtual void ReleaseCachedFonts() OVERRIDE;
#endif
virtual void UpdateHistograms(int sequence_number) OVERRIDE;

//////////////////////////////////////////////////////////////////////////
// The following functions are called by the test itself.
Expand Down
19 changes: 15 additions & 4 deletions content/renderer/render_thread_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,21 @@ void RenderThreadImpl::SetIdleNotificationDelayInMs(
idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
}

void RenderThreadImpl::ToggleWebKitSharedTimer(bool suspend) {
if (suspend_webkit_shared_timer_) {
EnsureWebKitInitialized();
if (suspend) {
webkit_platform_support_->SuspendSharedTimer();
} else {
webkit_platform_support_->ResumeSharedTimer();
}
}
}

void RenderThreadImpl::UpdateHistograms(int sequence_number) {
child_histogram_message_filter()->SendHistograms(sequence_number);
}

void RenderThreadImpl::PostponeIdleNotification() {
idle_notifications_to_skip_ = 2;
}
Expand Down Expand Up @@ -775,10 +790,6 @@ void RenderThreadImpl::ReleaseCachedFonts() {

#endif // OS_WIN

void RenderThreadImpl::UpdateHistograms(int sequence_number) {
child_histogram_message_filter()->SendHistograms(sequence_number);
}

bool RenderThreadImpl::IsWebFrameValid(WebKit::WebFrame* web_frame) {
if (!web_frame)
return false; // We must be shutting down.
Expand Down
3 changes: 2 additions & 1 deletion content/renderer/render_thread_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,12 @@ class CONTENT_EXPORT RenderThreadImpl : public content::RenderThread,
virtual int64 GetIdleNotificationDelayInMs() const OVERRIDE;
virtual void SetIdleNotificationDelayInMs(
int64 idle_notification_delay_in_ms) OVERRIDE;
virtual void ToggleWebKitSharedTimer(bool suspend) OVERRIDE;
virtual void UpdateHistograms(int sequence_number) OVERRIDE;
#if defined(OS_WIN)
virtual void PreCacheFont(const LOGFONT& log_font) OVERRIDE;
virtual void ReleaseCachedFonts() OVERRIDE;
#endif
virtual void UpdateHistograms(int sequence_number) OVERRIDE;

// content::ChildThread:
virtual bool IsWebFrameValid(WebKit::WebFrame* frame) OVERRIDE;
Expand Down
9 changes: 6 additions & 3 deletions content/test/mock_render_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ void MockRenderThread::SetIdleNotificationDelayInMs(
int64 idle_notification_delay_in_ms) {
}

void MockRenderThread::ToggleWebKitSharedTimer(bool suspend) {
}

void MockRenderThread::UpdateHistograms(int sequence_number) {
}

#if defined(OS_WIN)
void MockRenderThread::PreCacheFont(const LOGFONT& log_font) {
}
Expand All @@ -174,9 +180,6 @@ void MockRenderThread::ReleaseCachedFonts() {

#endif // OS_WIN

void MockRenderThread::UpdateHistograms(int sequence_number) {
}

void MockRenderThread::SendCloseMessage() {
ViewMsg_Close msg(routing_id_);
widget_->OnMessageReceived(msg);
Expand Down

0 comments on commit a1a7ff3

Please sign in to comment.