<commit_before>// Copyright (c) 2011 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/browser_about_handler.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/i18n/number_formatting.h"
#include "base/json/json_writer.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_table.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/threading/thread.h"
#include "base/tracked_objects.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#include "chrome/common/about_handler.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/gpu_process_host.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "googleurl/src/gurl.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/webkit_glue.h"
#ifdef CHROME_V8
#include "v8/include/v8.h"
#endif

#if defined(OS_WIN)
#include "chrome/browser/enumerate_modules_model_win.h"
#elif defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/cros/syslogs_library.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/version_loader.h"
#include "content/browser/zygote_host_linux.h"
#elif defined(OS_LINUX)
#include "content/browser/zygote_host_linux.h"
#endif

#if defined(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
#endif

using base::Time;
using base::TimeDelta;

#if defined(USE_TCMALLOC)
// static
AboutTcmallocOutputs* AboutTcmallocOutputs::GetInstance() {
  return Singleton<AboutTcmallocOutputs>::get();
}

AboutTcmallocOutputs::AboutTcmallocOutputs() {}

AboutTcmallocOutputs::~AboutTcmallocOutputs() {}

// Glue between the callback task and the method in the singleton.
void AboutTcmallocRendererCallback(base::ProcessId pid,
                                   const std::string& output) {
  AboutTcmallocOutputs::GetInstance()->RendererCallback(pid, output);
}
#endif

namespace {

// The (alphabetized) paths used for the about pages.
// Note: Keep these in sync with url_constants.h
const char kAppCacheInternalsPath[] = "appcache-internals";
const char kBlobInternalsPath[] = "blob-internals";
const char kCreditsPath[] = "credits";
const char kCachePath[] = "view-http-cache";
#if defined(OS_WIN)
const char kConflictsPath[] = "conflicts";
#endif
const char kDnsPath[] = "dns";
const char kFlagsPath[] = "flags";
const char kGpuPath[] = "gpu-internals";
const char kHistogramsPath[] = "histograms";
const char kMemoryRedirectPath[] = "memory-redirect";
const char kMemoryPath[] = "memory";
const char kStatsPath[] = "stats";
const char kTasksPath[] = "tasks";
const char kTcmallocPath[] = "tcmalloc";
const char kTermsPath[] = "terms";
const char kVersionPath[] = "version";
const char kAboutPath[] = "about";
// Not about:* pages, but included to make about:about look nicer
const char kNetInternalsPath[] = "net-internals";
const char kPluginsPath[] = "plugins";
const char kSyncInternalsPath[] = "sync-internals";

#if defined(OS_LINUX)
const char kLinuxProxyConfigPath[] = "linux-proxy-config";
const char kSandboxPath[] = "sandbox";
#endif

#if defined(OS_CHROMEOS)
const char kNetworkPath[] = "network";
const char kOSCreditsPath[] = "os-credits";
const char kEULAPathFormat[] = "/usr/share/chromeos-assets/eula/%s/eula.html";
#endif

// Add path here to be included in about:about
const char *kAllAboutPaths[] = {
  kAboutPath,
  kAppCacheInternalsPath,
  kBlobInternalsPath,
  kCachePath,
  kCreditsPath,
#if defined(OS_WIN)
  kConflictsPath,
#endif
  kDnsPath,
  kFlagsPath,
  kGpuPath,
  kHistogramsPath,
  kMemoryPath,
  kNetInternalsPath,
  kPluginsPath,
  kStatsPath,
  kSyncInternalsPath,
#ifdef TRACK_ALL_TASK_OBJECTS
  kTasksPath,
#endif  // TRACK_ALL_TASK_OBJECTS
  kTcmallocPath,
  kTermsPath,
  kVersionPath,
#if defined(OS_LINUX)
  kSandboxPath,
#endif
#if defined(OS_CHROMEOS)
  kNetworkPath,
  kOSCreditsPath,
#endif
  };

// When you type about:memory, it actually loads an intermediate URL that
// redirects you to the final page. This avoids the problem where typing
// "about:memory" on the new tab page or any other page where a process
// transition would occur to the about URL will cause some confusion.
//
// The problem is that during the processing of the memory page, there are two
// processes active, the original and the destination one. This can create the
// impression that we're using more resources than we actually are. This
// redirect solves the problem by eliminating the process transition during the
// time that about memory is being computed.
std::string GetAboutMemoryRedirectResponse() {
  return "<meta http-equiv=\"refresh\" "
      "content=\"0;chrome://about/memory\">";
}

class AboutSource : public ChromeURLDataManager::DataSource {
 public:
  // Creates our datasource.
  AboutSource();

  // Called when the network layer has requested a resource underneath
  // the path we registered.
  virtual void StartDataRequest(const std::string& path,
                                bool is_incognito,
                                int request_id);

  virtual std::string GetMimeType(const std::string&) const {
    return "text/html";
  }

  // Send the response data.
  void FinishDataRequest(const std::string& html, int request_id);

 private:
  virtual ~AboutSource();

  DISALLOW_COPY_AND_ASSIGN(AboutSource);
};

// Handling about:memory is complicated enough to encapsulate its related
// methods into a single class. The user should create it (on the heap) and call
// its |StartFetch()| method.
class AboutMemoryHandler : public MemoryDetails {
 public:
  AboutMemoryHandler(AboutSource* source, int request_id)
    : source_(source), request_id_(request_id) {}


  virtual void OnDetailsAvailable();

 private:
  ~AboutMemoryHandler() {}

  void BindProcessMetrics(DictionaryValue* data,
                          ProcessMemoryInformation* info);
  void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info);

  scoped_refptr<AboutSource> source_;
  int request_id_;

  DISALLOW_COPY_AND_ASSIGN(AboutMemoryHandler);
};

#if defined(OS_CHROMEOS)
// ChromeOSAboutVersionHandler is responsible for loading the Chrome OS
// version.
// ChromeOSAboutVersionHandler handles deleting itself once the version has
// been obtained and AboutSource notified.
class ChromeOSAboutVersionHandler {
 public:
  ChromeOSAboutVersionHandler(AboutSource* source, int request_id);

  // Callback from chromeos::VersionLoader giving the version.
  void OnVersion(chromeos::VersionLoader::Handle handle,
                 std::string version);

 private:
  // Where the results are fed to.
  scoped_refptr<AboutSource> source_;

  // ID identifying the request.
  int request_id_;

  // Handles asynchronously loading the version.
  chromeos::VersionLoader loader_;

  // Used to request the version.
  CancelableRequestConsumer consumer_;

  DISALLOW_COPY_AND_ASSIGN(ChromeOSAboutVersionHandler);
};

class ChromeOSTermsHandler
    : public base::RefCountedThreadSafe<ChromeOSTermsHandler> {
 public:
  static void Start(AboutSource* source, int request_id) {
    scoped_refptr<ChromeOSTermsHandler> handler(
        new ChromeOSTermsHandler(source, request_id));
    handler->StartOnUIThread();
  }

 private:
  ChromeOSTermsHandler(AboutSource* source, int request_id)
    : source_(source),
      request_id_(request_id),
      locale_(WizardController::GetInitialLocale()) {
  }

  void StartOnUIThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(this, &ChromeOSTermsHandler::LoadFileOnFileThread));
  }

  void LoadFileOnFileThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    std::string path = StringPrintf(kEULAPathFormat, locale_.c_str());
    if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
      // No EULA for given language - try en-US as default.
      path = StringPrintf(kEULAPathFormat, "en-US");
      if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
        // Last resort use EULA from resources.
        contents_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
            IDR_TERMS_HTML).as_string();
      }
    }
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &ChromeOSTermsHandler::ResponseOnUIThread));
  }

  void ResponseOnUIThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    source_->FinishDataRequest(contents_, request_id_);
  }

  // Where the results are fed to.
  scoped_refptr<AboutSource> source_;
<commit_msg>Load EULA from resources only on UI thread for Chrome OS<commit_after>// Copyright (c) 2011 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/browser_about_handler.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/i18n/number_formatting.h"
#include "base/json/json_writer.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_table.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/threading/thread.h"
#include "base/tracked_objects.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/net/predictor_api.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#include "chrome/common/about_handler.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/gpu_process_host.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "googleurl/src/gurl.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/glue/webkit_glue.h"
#ifdef CHROME_V8
#include "v8/include/v8.h"
#endif

#if defined(OS_WIN)
#include "chrome/browser/enumerate_modules_model_win.h"
#elif defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/cros/syslogs_library.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/version_loader.h"
#include "content/browser/zygote_host_linux.h"
#elif defined(OS_LINUX)
#include "content/browser/zygote_host_linux.h"
#endif

#if defined(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
#endif

using base::Time;
using base::TimeDelta;

#if defined(USE_TCMALLOC)
// static
AboutTcmallocOutputs* AboutTcmallocOutputs::GetInstance() {
  return Singleton<AboutTcmallocOutputs>::get();
}

AboutTcmallocOutputs::AboutTcmallocOutputs() {}

AboutTcmallocOutputs::~AboutTcmallocOutputs() {}

// Glue between the callback task and the method in the singleton.
void AboutTcmallocRendererCallback(base::ProcessId pid,
                                   const std::string& output) {
  AboutTcmallocOutputs::GetInstance()->RendererCallback(pid, output);
}
#endif

namespace {

// The (alphabetized) paths used for the about pages.
// Note: Keep these in sync with url_constants.h
const char kAppCacheInternalsPath[] = "appcache-internals";
const char kBlobInternalsPath[] = "blob-internals";
const char kCreditsPath[] = "credits";
const char kCachePath[] = "view-http-cache";
#if defined(OS_WIN)
const char kConflictsPath[] = "conflicts";
#endif
const char kDnsPath[] = "dns";
const char kFlagsPath[] = "flags";
const char kGpuPath[] = "gpu-internals";
const char kHistogramsPath[] = "histograms";
const char kMemoryRedirectPath[] = "memory-redirect";
const char kMemoryPath[] = "memory";
const char kStatsPath[] = "stats";
const char kTasksPath[] = "tasks";
const char kTcmallocPath[] = "tcmalloc";
const char kTermsPath[] = "terms";
const char kVersionPath[] = "version";
const char kAboutPath[] = "about";
// Not about:* pages, but included to make about:about look nicer
const char kNetInternalsPath[] = "net-internals";
const char kPluginsPath[] = "plugins";
const char kSyncInternalsPath[] = "sync-internals";

#if defined(OS_LINUX)
const char kLinuxProxyConfigPath[] = "linux-proxy-config";
const char kSandboxPath[] = "sandbox";
#endif

#if defined(OS_CHROMEOS)
const char kNetworkPath[] = "network";
const char kOSCreditsPath[] = "os-credits";
const char kEULAPathFormat[] = "/usr/share/chromeos-assets/eula/%s/eula.html";
#endif

// Add path here to be included in about:about
const char *kAllAboutPaths[] = {
  kAboutPath,
  kAppCacheInternalsPath,
  kBlobInternalsPath,
  kCachePath,
  kCreditsPath,
#if defined(OS_WIN)
  kConflictsPath,
#endif
  kDnsPath,
  kFlagsPath,
  kGpuPath,
  kHistogramsPath,
  kMemoryPath,
  kNetInternalsPath,
  kPluginsPath,
  kStatsPath,
  kSyncInternalsPath,
#ifdef TRACK_ALL_TASK_OBJECTS
  kTasksPath,
#endif  // TRACK_ALL_TASK_OBJECTS
  kTcmallocPath,
  kTermsPath,
  kVersionPath,
#if defined(OS_LINUX)
  kSandboxPath,
#endif
#if defined(OS_CHROMEOS)
  kNetworkPath,
  kOSCreditsPath,
#endif
  };

// When you type about:memory, it actually loads an intermediate URL that
// redirects you to the final page. This avoids the problem where typing
// "about:memory" on the new tab page or any other page where a process
// transition would occur to the about URL will cause some confusion.
//
// The problem is that during the processing of the memory page, there are two
// processes active, the original and the destination one. This can create the
// impression that we're using more resources than we actually are. This
// redirect solves the problem by eliminating the process transition during the
// time that about memory is being computed.
std::string GetAboutMemoryRedirectResponse() {
  return "<meta http-equiv=\"refresh\" "
      "content=\"0;chrome://about/memory\">";
}

class AboutSource : public ChromeURLDataManager::DataSource {
 public:
  // Creates our datasource.
  AboutSource();

  // Called when the network layer has requested a resource underneath
  // the path we registered.
  virtual void StartDataRequest(const std::string& path,
                                bool is_incognito,
                                int request_id);

  virtual std::string GetMimeType(const std::string&) const {
    return "text/html";
  }

  // Send the response data.
  void FinishDataRequest(const std::string& html, int request_id);

 private:
  virtual ~AboutSource();

  DISALLOW_COPY_AND_ASSIGN(AboutSource);
};

// Handling about:memory is complicated enough to encapsulate its related
// methods into a single class. The user should create it (on the heap) and call
// its |StartFetch()| method.
class AboutMemoryHandler : public MemoryDetails {
 public:
  AboutMemoryHandler(AboutSource* source, int request_id)
    : source_(source), request_id_(request_id) {}


  virtual void OnDetailsAvailable();

 private:
  ~AboutMemoryHandler() {}

  void BindProcessMetrics(DictionaryValue* data,
                          ProcessMemoryInformation* info);
  void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info);

  scoped_refptr<AboutSource> source_;
  int request_id_;

  DISALLOW_COPY_AND_ASSIGN(AboutMemoryHandler);
};

#if defined(OS_CHROMEOS)
// ChromeOSAboutVersionHandler is responsible for loading the Chrome OS
// version.
// ChromeOSAboutVersionHandler handles deleting itself once the version has
// been obtained and AboutSource notified.
class ChromeOSAboutVersionHandler {
 public:
  ChromeOSAboutVersionHandler(AboutSource* source, int request_id);

  // Callback from chromeos::VersionLoader giving the version.
  void OnVersion(chromeos::VersionLoader::Handle handle,
                 std::string version);

 private:
  // Where the results are fed to.
  scoped_refptr<AboutSource> source_;

  // ID identifying the request.
  int request_id_;

  // Handles asynchronously loading the version.
  chromeos::VersionLoader loader_;

  // Used to request the version.
  CancelableRequestConsumer consumer_;

  DISALLOW_COPY_AND_ASSIGN(ChromeOSAboutVersionHandler);
};

class ChromeOSTermsHandler
    : public base::RefCountedThreadSafe<ChromeOSTermsHandler> {
 public:
  static void Start(AboutSource* source, int request_id) {
    scoped_refptr<ChromeOSTermsHandler> handler(
        new ChromeOSTermsHandler(source, request_id));
    handler->StartOnUIThread();
  }

 private:
  ChromeOSTermsHandler(AboutSource* source, int request_id)
    : source_(source),
      request_id_(request_id),
      locale_(WizardController::GetInitialLocale()) {
  }

  void StartOnUIThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    BrowserThread::PostTask(
        BrowserThread::FILE, FROM_HERE,
        NewRunnableMethod(this, &ChromeOSTermsHandler::LoadFileOnFileThread));
  }

  void LoadFileOnFileThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    std::string path = StringPrintf(kEULAPathFormat, locale_.c_str());
    if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
      // No EULA for given language - try en-US as default.
      path = StringPrintf(kEULAPathFormat, "en-US");
      if (!file_util::ReadFileToString(FilePath(path), &contents_)) {
        // File with EULA not found, ResponseOnUIThread will load EULA from
        // resources if contents_ is empty.
        contents_.clear();
      }
    }
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &ChromeOSTermsHandler::ResponseOnUIThread));
  }

  void ResponseOnUIThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    if (contents_.empty()) {
      contents_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
          IDR_TERMS_HTML).as_string();
    }
    source_->FinishDataRequest(contents_, request_id_);
  }

  // Where the results are fed to.
  scoped_refptr<AboutSource> source_;

{'fraction_non_alphanumeric': 0.11221666747561035, 'fraction_numerical': 0.0013590253846527205, 'mean_word_length': 4.968713789107763, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4110152', 'n_tokens_mistral': 6594, 'n_tokens_neox': 6453, 'n_words': 1538}