test_utils.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Use of this source code is governed by a BSD-style license that can be
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// found in the LICENSE file.
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/test/test_utils.h"
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/bind.h"
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/message_loop/message_loop.h"
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/run_loop.h"
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/strings/utf_string_conversions.h"
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "base/values.h"
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/browser/browser_child_process_host_iterator.h"
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/browser/notification_service.h"
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/browser/render_process_host.h"
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/browser/render_view_host.h"
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/common/process_type.h"
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "content/public/test/test_launcher.h"
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "testing/gtest/include/gtest/gtest.h"
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace content {
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace {
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Number of times to repost a Quit task so that the MessageLoop finishes up
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// pending tasks and tasks posted by those pending tasks without risking the
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// potential hang behavior of MessageLoop::QuitWhenIdle.
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// The criteria for choosing this number: it should be high enough to make the
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// quit act like QuitWhenIdle, while taking into account that any page which is
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// animating may be rendering another frame for each quit deferral. For an
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// animating page, the potential delay to quitting the RunLoop would be
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// kNumQuitDeferrals * frame_render_time. Some perf tests run slow, such as
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// 200ms/frame.
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int kNumQuitDeferrals = 10;
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void DeferredQuitRunLoop(const base::Closure& quit_task,
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                                int num_quit_deferrals) {
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (num_quit_deferrals <= 0) {
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    quit_task.Run();
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  } else {
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    base::MessageLoop::current()->PostTask(
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        FROM_HERE,
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1));
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  }
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RunAllPendingMessageAndSendQuit(BrowserThread::ID thread_id,
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                                     const base::Closure& quit_task) {
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RunAllPendingInMessageLoop();
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  BrowserThread::PostTask(thread_id, FROM_HERE, quit_task);
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Class used handle result callbacks for ExecuteScriptAndGetValue.
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ScriptCallback {
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public:
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  ScriptCallback() { }
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  virtual ~ScriptCallback() { }
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  void ResultCallback(const base::Value* result);
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  scoped_ptr<base::Value> result() { return result_.Pass(); }
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry private:
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  scoped_ptr<base::Value> result_;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  DISALLOW_COPY_AND_ASSIGN(ScriptCallback);
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ScriptCallback::ResultCallback(const base::Value* result) {
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (result)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    result_.reset(result->DeepCopy());
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::MessageLoop::current()->Quit();
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Adapter that makes a WindowedNotificationObserver::ConditionTestCallback from
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// a WindowedNotificationObserver::ConditionTestCallbackWithoutSourceAndDetails
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// by ignoring the notification source and details.
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool IgnoreSourceAndDetails(
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const WindowedNotificationObserver::
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry        ConditionTestCallbackWithoutSourceAndDetails& callback,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationSource& source,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationDetails& details) {
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  return callback.Run();
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}  // namespace
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RunMessageLoop() {
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::RunLoop run_loop;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RunThisRunLoop(&run_loop);
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RunThisRunLoop(base::RunLoop* run_loop) {
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::MessageLoop::ScopedNestableTaskAllower allow(
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      base::MessageLoop::current());
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // If we're running inside a browser test, we might need to allow the test
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // launcher to do extra work before/after running a nested message loop.
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  TestLauncherDelegate* delegate = NULL;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(OS_IOS)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  delegate = GetCurrentTestLauncherDelegate();
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (delegate)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    delegate->PreRunMessageLoop(run_loop);
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  run_loop->Run();
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (delegate)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    delegate->PostRunMessageLoop();
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RunAllPendingInMessageLoop() {
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::MessageLoop::current()->PostTask(
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RunMessageLoop();
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RunAllPendingInMessageLoop(BrowserThread::ID thread_id) {
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (BrowserThread::CurrentlyOn(thread_id)) {
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    RunAllPendingInMessageLoop();
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  }
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  BrowserThread::ID current_thread_id;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (!BrowserThread::GetCurrentThreadIdentifier(&current_thread_id)) {
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    NOTREACHED();
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  }
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::RunLoop run_loop;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  BrowserThread::PostTask(thread_id, FROM_HERE,
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id,
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                 run_loop.QuitClosure()));
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RunThisRunLoop(&run_loop);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybase::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop) {
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  return base::Bind(&DeferredQuitRunLoop, run_loop->QuitClosure(),
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry                    kNumQuitDeferrals);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryscoped_ptr<base::Value> ExecuteScriptAndGetValue(
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    RenderViewHost* render_view_host,
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const std::string& script) {
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  ScriptCallback observer;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  render_view_host->ExecuteJavascriptInWebFrameCallbackResult(
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      base::string16(),  // frame_xpath,
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      base::UTF8ToUTF16(script),
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      base::Bind(&ScriptCallback::ResultCallback, base::Unretained(&observer)));
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  base::MessageLoop* loop = base::MessageLoop::current();
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  loop->Run();
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  return observer.result().Pass();
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMessageLoopRunner::MessageLoopRunner()
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    : loop_running_(false),
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      quit_closure_called_(false) {
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMessageLoopRunner::~MessageLoopRunner() {
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MessageLoopRunner::Run() {
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // Do not run the message loop if our quit closure has already been called.
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // This helps in scenarios where the closure has a chance to run before
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // we Run explicitly.
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (quit_closure_called_)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  loop_running_ = true;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RunThisRunLoop(&run_loop_);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybase::Closure MessageLoopRunner::QuitClosure() {
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  return base::Bind(&MessageLoopRunner::Quit, this);
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MessageLoopRunner::Quit() {
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  quit_closure_called_ = true;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  // Only run the quit task if we are running the message loop.
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (loop_running_) {
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    GetQuitTaskForRunLoop(&run_loop_).Run();
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    loop_running_ = false;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  }
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowedNotificationObserver::WindowedNotificationObserver(
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int notification_type,
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationSource& source)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    : seen_(false),
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      running_(false),
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      source_(NotificationService::AllSources()) {
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  AddNotificationType(notification_type, source);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowedNotificationObserver::WindowedNotificationObserver(
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int notification_type,
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const ConditionTestCallback& callback)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    : seen_(false),
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      running_(false),
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      callback_(callback),
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      source_(NotificationService::AllSources()) {
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  AddNotificationType(notification_type, source_);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowedNotificationObserver::WindowedNotificationObserver(
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int notification_type,
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const ConditionTestCallbackWithoutSourceAndDetails& callback)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    : seen_(false),
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      running_(false),
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      callback_(base::Bind(&IgnoreSourceAndDetails, callback)),
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry      source_(NotificationService::AllSources()) {
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  registrar_.Add(this, notification_type, source_);
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindowedNotificationObserver::~WindowedNotificationObserver() {}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid WindowedNotificationObserver::AddNotificationType(
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int notification_type,
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationSource& source) {
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  registrar_.Add(this, notification_type, source);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid WindowedNotificationObserver::Wait() {
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (seen_)
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  running_ = true;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  message_loop_runner_ = new MessageLoopRunner;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  message_loop_runner_->Run();
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  EXPECT_TRUE(seen_);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid WindowedNotificationObserver::Observe(
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    int type,
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationSource& source,
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const NotificationDetails& details) {
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  source_ = source;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  details_ = details;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (!callback_.is_null() && !callback_.Run(source, details))
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  seen_ = true;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (!running_)
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  message_loop_runner_->Quit();
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  running_ = false;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInProcessUtilityThreadHelper::InProcessUtilityThreadHelper()
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    : child_thread_count_(0) {
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RenderProcessHost::SetRunRendererInProcess(true);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  BrowserChildProcessObserver::Add(this);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInProcessUtilityThreadHelper::~InProcessUtilityThreadHelper() {
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (child_thread_count_) {
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::UI));
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO));
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    runner_ = new MessageLoopRunner;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    runner_->Run();
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  }
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  BrowserChildProcessObserver::Remove(this);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  RenderProcessHost::SetRunRendererInProcess(false);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InProcessUtilityThreadHelper::BrowserChildProcessHostConnected(
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const ChildProcessData& data) {
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  child_thread_count_++;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InProcessUtilityThreadHelper::BrowserChildProcessHostDisconnected(
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const ChildProcessData& data) {
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (--child_thread_count_)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    return;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  if (runner_.get())
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    runner_->Quit();
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}  // namespace content
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry