<commit_before>// Copyright (c) 2009 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/worker_host/worker_process_host.h"

#include <set>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug_util.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/appcache/appcache_dispatcher_host.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/database_dispatcher_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/worker_host/message_port_dispatcher.h"
#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/debug_flags.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/result_codes.h"
#include "chrome/common/worker_messages.h"
#include "ipc/ipc_switches.h"
#include "net/base/registry_controlled_domain.h"

// Notifies RenderViewHost that one or more worker objects crashed.
class WorkerCrashTask : public Task {
 public:
  WorkerCrashTask(int render_process_unique_id, int render_view_id)
      : render_process_unique_id_(render_process_unique_id),
        render_view_id_(render_view_id) { }

  void Run() {
    RenderViewHost* host =
        RenderViewHost::FromID(render_process_unique_id_, render_view_id_);
    if (host) {
      RenderViewHostDelegate::BrowserIntegration* integration_delegate =
          host->delegate()->GetBrowserIntegrationDelegate();
      if (integration_delegate)
        integration_delegate->OnCrashedWorker();
    }
  }

 private:
  int render_process_unique_id_;
  int render_view_id_;
};

WorkerProcessHost::WorkerProcessHost(
    ResourceDispatcherHost* resource_dispatcher_host,
    ChromeURLRequestContext *request_context)
    : BrowserChildProcessHost(WORKER_PROCESS, resource_dispatcher_host),
      request_context_(request_context),
      appcache_dispatcher_host_(
          new AppCacheDispatcherHost(request_context)) {
  next_route_id_callback_.reset(NewCallbackWithReturnValue(
      WorkerService::GetInstance(), &WorkerService::next_worker_route_id));
  db_dispatcher_host_ = new DatabaseDispatcherHost(
      request_context->database_tracker(), this,
      request_context_->host_content_settings_map());
  appcache_dispatcher_host_->Initialize(this);
}

WorkerProcessHost::~WorkerProcessHost() {
  // Shut down the database dispatcher host.
  db_dispatcher_host_->Shutdown();

  // Let interested observers know we are being deleted.
  NotificationService::current()->Notify(
      NotificationType::WORKER_PROCESS_HOST_SHUTDOWN,
      Source<WorkerProcessHost>(this),
      NotificationService::NoDetails());

  // If we crashed, tell the RenderViewHosts.
  for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
    const WorkerDocumentSet::DocumentInfoSet& parents =
        i->worker_document_set()->documents();
    for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
             parents.begin(); parent_iter != parents.end(); ++parent_iter) {
      ChromeThread::PostTask(
          ChromeThread::UI, FROM_HERE,
          new WorkerCrashTask(parent_iter->renderer_id(),
                              parent_iter->render_view_route_id()));
    }
  }

  ChildProcessSecurityPolicy::GetInstance()->Remove(id());
}

bool WorkerProcessHost::Init() {
  if (!CreateChannel())
    return false;

  FilePath exe_path = GetChildPath(true);
  if (exe_path.empty())
    return false;

  CommandLine* cmd_line = new CommandLine(exe_path);
  cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess);
  cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
  SetCrashReporterCommandLine(cmd_line);

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableNativeWebWorkers)) {
    cmd_line->AppendSwitch(switches::kEnableNativeWebWorkers);
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kWebWorkerShareProcesses)) {
    cmd_line->AppendSwitch(switches::kWebWorkerShareProcesses);
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableApplicationCache)) {
    cmd_line->AppendSwitch(switches::kDisableApplicationCache);
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableDatabases)) {
    cmd_line->AppendSwitch(switches::kDisableDatabases);
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableLogging)) {
    cmd_line->AppendSwitch(switches::kEnableLogging);
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kLoggingLevel)) {
    const std::string level =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kLoggingLevel);
    cmd_line->AppendSwitchASCII(switches::kLoggingLevel, level);
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableWebSockets)) {
    cmd_line->AppendSwitch(switches::kDisableWebSockets);
  }

#if defined(OS_WIN)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableDesktopNotifications)) {
    cmd_line->AppendSwitch(switches::kDisableDesktopNotifications);
  }
#endif

#if defined(OS_POSIX)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kWaitForDebuggerChildren)) {<commit_msg>Use new CopySwitchesFrom CommandLine API to simplify some code.<commit_after>// Copyright (c) 2009 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/worker_host/worker_process_host.h"

#include <set>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug_util.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/appcache/appcache_dispatcher_host.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/database_dispatcher_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/worker_host/message_port_dispatcher.h"
#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/debug_flags.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/result_codes.h"
#include "chrome/common/worker_messages.h"
#include "ipc/ipc_switches.h"
#include "net/base/registry_controlled_domain.h"

// Notifies RenderViewHost that one or more worker objects crashed.
class WorkerCrashTask : public Task {
 public:
  WorkerCrashTask(int render_process_unique_id, int render_view_id)
      : render_process_unique_id_(render_process_unique_id),
        render_view_id_(render_view_id) { }

  void Run() {
    RenderViewHost* host =
        RenderViewHost::FromID(render_process_unique_id_, render_view_id_);
    if (host) {
      RenderViewHostDelegate::BrowserIntegration* integration_delegate =
          host->delegate()->GetBrowserIntegrationDelegate();
      if (integration_delegate)
        integration_delegate->OnCrashedWorker();
    }
  }

 private:
  int render_process_unique_id_;
  int render_view_id_;
};

WorkerProcessHost::WorkerProcessHost(
    ResourceDispatcherHost* resource_dispatcher_host,
    ChromeURLRequestContext *request_context)
    : BrowserChildProcessHost(WORKER_PROCESS, resource_dispatcher_host),
      request_context_(request_context),
      appcache_dispatcher_host_(
          new AppCacheDispatcherHost(request_context)) {
  next_route_id_callback_.reset(NewCallbackWithReturnValue(
      WorkerService::GetInstance(), &WorkerService::next_worker_route_id));
  db_dispatcher_host_ = new DatabaseDispatcherHost(
      request_context->database_tracker(), this,
      request_context_->host_content_settings_map());
  appcache_dispatcher_host_->Initialize(this);
}

WorkerProcessHost::~WorkerProcessHost() {
  // Shut down the database dispatcher host.
  db_dispatcher_host_->Shutdown();

  // Let interested observers know we are being deleted.
  NotificationService::current()->Notify(
      NotificationType::WORKER_PROCESS_HOST_SHUTDOWN,
      Source<WorkerProcessHost>(this),
      NotificationService::NoDetails());

  // If we crashed, tell the RenderViewHosts.
  for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
    const WorkerDocumentSet::DocumentInfoSet& parents =
        i->worker_document_set()->documents();
    for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter =
             parents.begin(); parent_iter != parents.end(); ++parent_iter) {
      ChromeThread::PostTask(
          ChromeThread::UI, FROM_HERE,
          new WorkerCrashTask(parent_iter->renderer_id(),
                              parent_iter->render_view_route_id()));
    }
  }

  ChildProcessSecurityPolicy::GetInstance()->Remove(id());
}

bool WorkerProcessHost::Init() {
  if (!CreateChannel())
    return false;

  FilePath exe_path = GetChildPath(true);
  if (exe_path.empty())
    return false;

  CommandLine* cmd_line = new CommandLine(exe_path);
  cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess);
  cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
  SetCrashReporterCommandLine(cmd_line);

  static const char* const kSwitchNames[] = {
    switches::kEnableNativeWebWorkers,
    switches::kWebWorkerShareProcesses,
    switches::kDisableApplicationCache,
    switches::kDisableDatabases,
    switches::kEnableLogging,
    switches::kLoggingLevel,
    switches::kDisableWebSockets,
#if defined(OS_WIN)
    switches::kDisableDesktopNotifications,
#endif
  };
  cmd_line->CopySwitchesFrom(*CommandLine::ForCurrentProcess(), kSwitchNames,
                             arraysize(kSwitchNames));

#if defined(OS_POSIX)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kWaitForDebuggerChildren)) {
{'fraction_non_alphanumeric': 0.11140952028153361, 'fraction_numerical': 0.0007408779403593258, 'mean_word_length': 5.245806824754193, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3864187', 'n_tokens_mistral': 3268, 'n_tokens_neox': 3222, 'n_words': 514}