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
3 // found in the LICENSE file.
8 #include "base/android/jni_android.h"
9 #include "base/android/jni_string.h"
10 #include "base/android/scoped_java_ref.h"
11 #include "base/basictypes.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "content/browser/android/content_view_statics.h"
15 #include "content/common/android/address_parser.h"
16 #include "content/common/view_messages.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_process_host_observer.h"
19 #include "jni/ContentViewStatics_jni.h"
21 using base::android::ConvertJavaStringToUTF16
;
22 using base::android::ConvertUTF16ToJavaString
;
26 // TODO(pliard): http://crbug.com/235909. Move WebKit shared timer toggling
27 // functionality out of ContentViewStatistics and not be build on top of
28 // blink::Platform::SuspendSharedTimer.
29 // TODO(pliard): http://crbug.com/235912. Add unit tests for WebKit shared timer
32 // This tracks the renderer processes that received a suspend request. It's
33 // important on resume to only resume the renderer processes that were actually
34 // suspended as opposed to all the current renderer processes because the
35 // suspend calls are refcounted within BlinkPlatformImpl and it expects a
36 // perfectly matched number of resume calls.
37 // Note that this class is only accessed from the UI thread.
38 class SuspendedProcessWatcher
: public content::RenderProcessHostObserver
{
41 // If the process crashes, stop watching the corresponding RenderProcessHost
42 // and ensure it doesn't get over-resumed.
43 virtual void RenderProcessExited(content::RenderProcessHost
* host
,
44 base::TerminationStatus status
,
45 int exit_code
) override
{
49 virtual void RenderProcessHostDestroyed(
50 content::RenderProcessHost
* host
) override
{
54 // Suspends timers in all current render processes.
55 void SuspendWebKitSharedTimers() {
56 DCHECK(suspended_processes_
.empty());
58 for (content::RenderProcessHost::iterator
i(
59 content::RenderProcessHost::AllHostsIterator());
60 !i
.IsAtEnd(); i
.Advance()) {
61 content::RenderProcessHost
* host
= i
.GetCurrentValue();
62 host
->AddObserver(this);
63 host
->Send(new ViewMsg_SetWebKitSharedTimersSuspended(true));
64 suspended_processes_
.push_back(host
->GetID());
68 // Resumes timers in processes that were previously stopped.
69 void ResumeWebkitSharedTimers() {
70 for (std::vector
<int>::const_iterator it
= suspended_processes_
.begin();
71 it
!= suspended_processes_
.end(); ++it
) {
72 content::RenderProcessHost
* host
=
73 content::RenderProcessHost::FromID(*it
);
75 host
->RemoveObserver(this);
76 host
->Send(new ViewMsg_SetWebKitSharedTimersSuspended(false));
78 suspended_processes_
.clear();
82 void StopWatching(content::RenderProcessHost
* host
) {
83 std::vector
<int>::iterator pos
= std::find(suspended_processes_
.begin(),
84 suspended_processes_
.end(),
86 DCHECK(pos
!= suspended_processes_
.end());
87 host
->RemoveObserver(this);
88 suspended_processes_
.erase(pos
);
91 std::vector
<int /* RenderProcessHost id */> suspended_processes_
;
94 base::LazyInstance
<SuspendedProcessWatcher
> g_suspended_processes_watcher
=
95 LAZY_INSTANCE_INITIALIZER
;
99 // Returns the first substring consisting of the address of a physical location.
100 static jstring
FindAddress(JNIEnv
* env
, jclass clazz
, jstring addr
) {
101 base::string16 content_16
= ConvertJavaStringToUTF16(env
, addr
);
102 base::string16 result_16
;
103 if (content::address_parser::FindAddress(content_16
, &result_16
))
104 return ConvertUTF16ToJavaString(env
, result_16
).Release();
108 static void SetWebKitSharedTimersSuspended(JNIEnv
* env
,
112 g_suspended_processes_watcher
.Pointer()->SuspendWebKitSharedTimers();
114 g_suspended_processes_watcher
.Pointer()->ResumeWebkitSharedTimers();
120 bool RegisterWebViewStatics(JNIEnv
* env
) {
121 return RegisterNativesImpl(env
);
124 } // namespace content