// Copyright 2014 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/metrics/plugin_metrics_provider.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>

#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/pref_names.h"
#include "components/metrics/proto/system_profile.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/process_type.h"
#include "content/public/common/webplugininfo.h"

namespace {

// Delay for RecordCurrentState execution.
const int kRecordStateDelayMs = 15 * base::Time::kMillisecondsPerSecond;

// Returns the plugin preferences corresponding for this user, if available.
// If multiple user profiles are loaded, returns the preferences corresponding
// to an arbitrary one of the profiles.
PluginPrefs* GetPluginPrefs() {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  if (!profile_manager) {
    // The profile manager can be NULL when testing.
    return NULL;
  }

  std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
  if (profiles.empty())
    return NULL;

  return PluginPrefs::GetForProfile(profiles.front()).get();
}

// Fills |plugin| with the info contained in |plugin_info| and |plugin_prefs|.
void SetPluginInfo(const content::WebPluginInfo& plugin_info,
                   const PluginPrefs* plugin_prefs,
                   metrics::SystemProfileProto::Plugin* plugin) {
  plugin->set_name(base::UTF16ToUTF8(plugin_info.name));
  plugin->set_filename(plugin_info.path.BaseName().AsUTF8Unsafe());
  plugin->set_version(base::UTF16ToUTF8(plugin_info.version));
  plugin->set_is_pepper(plugin_info.is_pepper_plugin());
  if (plugin_prefs)
    plugin->set_is_disabled(!plugin_prefs->IsPluginEnabled(plugin_info));
}

}  // namespace

// This is used to quickly log stats from child process related notifications in
// PluginMetricsProvider::child_stats_buffer_.  The buffer's contents are
// transferred out when Local State is periodically saved.  The information is
// then reported to the UMA server on next launch.
struct PluginMetricsProvider::ChildProcessStats {
 public:
  explicit ChildProcessStats(int process_type)
      : process_launches(0),
        process_crashes(0),
        instances(0),
        loading_errors(0),
        process_type(process_type) {}

  // This constructor is only used by the map to return some default value for
  // an index for which no value has been assigned.
  ChildProcessStats()
      : process_launches(0),
        process_crashes(0),
        instances(0),
        loading_errors(0),
        process_type(content::PROCESS_TYPE_UNKNOWN) {}

  // The number of times that the given child process has been launched
  int process_launches;

  // The number of times that the given child process has crashed
  int process_crashes;

  // The number of instances of this child process that have been created.
  // An instance is a DOM object rendered by this child process during a page
  // load.
  int instances;

  // The number of times there was an error loading an instance of this child
  // process.
  int loading_errors;

  int process_type;
};

PluginMetricsProvider::PluginMetricsProvider(PrefService* local_state)
    : local_state_(local_state),
      weak_ptr_factory_(this) {
  DCHECK(local_state_);

  BrowserChildProcessObserver::Add(this);
}

PluginMetricsProvider::~PluginMetricsProvider() {
  BrowserChildProcessObserver::Remove(this);
}

void PluginMetricsProvider::GetPluginInformation(
    const base::Closure& done_callback) {
  content::PluginService::GetInstance()->GetPlugins(
      base::Bind(&PluginMetricsProvider::OnGotPlugins,
                 weak_ptr_factory_.GetWeakPtr(),
                 done_callback));
}

void PluginMetricsProvider::ProvideSystemProfileMetrics(
    metrics::SystemProfileProto* system_profile_proto) {
  PluginPrefs* plugin_prefs = GetPluginPrefs();
  for (size_t i = 0; i < plugins_.size(); ++i) {
    SetPluginInfo(plugins_[i], plugin_prefs,
                  system_profile_proto->add_plugin());
  }
}

void PluginMetricsProvider::ProvideStabilityMetrics(
    metrics::SystemProfileProto* system_profile_proto) {
  RecordCurrentStateIfPending();
  const base::ListValue* plugin_stats_list = local_state_->GetList(
      prefs::kStabilityPluginStats);
  if (!plugin_stats_list)
    return;

  metrics::SystemProfileProto::Stability* stability =
      system_profile_proto->mutable_stability();
  for (const auto& value : *plugin_stats_list) {
    base::DictionaryValue* plugin_dict;
    if (!value->GetAsDictionary(&plugin_dict)) {
      NOTREACHED();
      continue;
    }

    // Note that this search is potentially a quadratic operation, but given the
    // low number of plugins installed on a "reasonable" setup, this should be
    // fine.
    // TODO(isherman): Verify that this does not show up as a hotspot in
    // profiler runs.
    const metrics::SystemProfileProto::Plugin* system_profile_plugin = NULL;
    std::string plugin_name;
    plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
    for (int i = 0; i < system_profile_proto->plugin_size(); ++i) {
      if (system_profile_proto->plugin(i).name() == plugin_name) {
        system_profile_plugin = &system_profile_proto->plugin(i);
        break;
      }
    }

    if (!system_profile_plugin) {
      NOTREACHED();
      continue;
    }

    metrics::SystemProfileProto::Stability::PluginStability* plugin_stability =
        stability->add_plugin_stability();
    *plugin_stability->mutable_plugin() = *system_profile_plugin;

    int launches = 0;
    plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
    if (launches > 0)
      plugin_stability->set_launch_count(launches);

    int instances = 0;
    plugin_dict->GetInteger(prefs::kStabilityPluginInstances, &instances);
    if (instances > 0)
      plugin_stability->set_instance_count(instances);

    int crashes = 0;
    plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes);
    if (crashes > 0)
      plugin_stability->set_crash_count(crashes);

    int loading_errors = 0;
    plugin_dict->GetInteger(prefs::kStabilityPluginLoadingErrors,
                            &loading_errors);
    if (loading_errors > 0)
      plugin_stability->set_loading_error_count(loading_errors);
  }

  local_state_->ClearPref(prefs::kStabilityPluginStats);
}

void PluginMetricsProvider::ClearSavedStabilityMetrics() {
  local_state_->ClearPref(prefs::kStabilityPluginStats);
}

// Saves plugin-related updates from the in-object buffer to Local State
// for retrieval next time we send a Profile log (generally next launch).
void PluginMetricsProvider::RecordCurrentState() {
  ListPrefUpdate update(local_state_, prefs::kStabilityPluginStats);
  base::ListValue* plugins = update.Get();
  DCHECK(plugins);

  for (const auto& value : *plugins) {
    base::DictionaryValue* plugin_dict;
    if (!value->GetAsDictionary(&plugin_dict)) {
      NOTREACHED();
      continue;
    }

    base::string16 plugin_name;
    plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
    if (plugin_name.empty()) {
      NOTREACHED();
      continue;
    }

    if (child_process_stats_buffer_.find(plugin_name) ==
        child_process_stats_buffer_.end()) {
      continue;
    }

    ChildProcessStats stats = child_process_stats_buffer_[plugin_name];
    if (stats.process_launches) {
      int launches = 0;
      plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
      launches += stats.process_launches;
      plugin_dict->SetInteger(prefs::kStabilityPluginLaunches, launches);
    }
    if (stats.process_crashes) {
      int crashes = 0;
      plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes);
      crashes += stats.process_crashes;
      plugin_dict->SetInteger(prefs::kStabilityPluginCrashes, crashes);
    }
    if (stats.instances) {
      int instances = 0;
      plugin_dict->GetInteger(prefs::kStabilityPluginInstances, &instances);
      instances += stats.instances;
      plugin_dict->SetInteger(prefs::kStabilityPluginInstances, instances);
    }
    if (stats.loading_errors) {
      int loading_errors = 0;
      plugin_dict->GetInteger(prefs::kStabilityPluginLoadingErrors,
                              &loading_errors);
      loading_errors += stats.loading_errors;
      plugin_dict->SetInteger(prefs::kStabilityPluginLoadingErrors,
                              loading_errors);
    }

    child_process_stats_buffer_.erase(plugin_name);
  }

  // Now go through and add dictionaries for plugins that didn't already have
  // reports in Local State.
  for (auto cache_iter = child_process_stats_buffer_.begin();
       cache_iter != child_process_stats_buffer_.end(); ++cache_iter) {
    ChildProcessStats stats = cache_iter->second;

    // Insert only plugins information into the plugins list.
    if (!IsPluginProcess(stats.process_type))
      continue;

    std::unique_ptr<base::DictionaryValue> plugin_dict(
        new base::DictionaryValue);

    plugin_dict->SetString(prefs::kStabilityPluginName, cache_iter->first);
    plugin_dict->SetInteger(prefs::kStabilityPluginLaunches,
                            stats.process_launches);
    plugin_dict->SetInteger(prefs::kStabilityPluginCrashes,
                            stats.process_crashes);
    plugin_dict->SetInteger(prefs::kStabilityPluginInstances,
                            stats.instances);
    plugin_dict->SetInteger(prefs::kStabilityPluginLoadingErrors,
                            stats.loading_errors);
    plugins->Append(std::move(plugin_dict));
  }
  child_process_stats_buffer_.clear();
}

void PluginMetricsProvider::LogPluginLoadingError(
    const base::FilePath& plugin_path) {
  content::WebPluginInfo plugin;
  bool success =
      content::PluginService::GetInstance()->GetPluginInfoByPath(plugin_path,
                                                                 &plugin);
  DCHECK(success);
  ChildProcessStats& stats = child_process_stats_buffer_[plugin.name];
  // Initialize the type if this entry is new.
  if (stats.process_type == content::PROCESS_TYPE_UNKNOWN) {
    // The plugin process might not actually be of type PPAPI_PLUGIN, but we
    // only care that it is *a* plugin process.
    stats.process_type = content::PROCESS_TYPE_PPAPI_PLUGIN;
  } else {
    DCHECK(IsPluginProcess(stats.process_type));
  }
  stats.loading_errors++;
  RecordCurrentStateWithDelay(kRecordStateDelayMs);
}

void PluginMetricsProvider::SetPluginsForTesting(
    const std::vector<content::WebPluginInfo>& plugins) {
  plugins_ = plugins;
}

// static
bool PluginMetricsProvider::IsPluginProcess(int process_type) {
  return (process_type == content::PROCESS_TYPE_PPAPI_PLUGIN ||
          process_type == content::PROCESS_TYPE_PPAPI_BROKER);
}

// static
void PluginMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterListPref(prefs::kStabilityPluginStats);
}

void PluginMetricsProvider::OnGotPlugins(
    const base::Closure& done_callback,
    const std::vector<content::WebPluginInfo>& plugins) {
  plugins_ = plugins;
  done_callback.Run();
}

PluginMetricsProvider::ChildProcessStats&
PluginMetricsProvider::GetChildProcessStats(
    const content::ChildProcessData& data) {
  const base::string16& child_name = data.name;
  if (!ContainsKey(child_process_stats_buffer_, child_name)) {
    child_process_stats_buffer_[child_name] =
        ChildProcessStats(data.process_type);
  }
  return child_process_stats_buffer_[child_name];
}

void PluginMetricsProvider::BrowserChildProcessHostConnected(
    const content::ChildProcessData& data) {
  GetChildProcessStats(data).process_launches++;
  RecordCurrentStateWithDelay(kRecordStateDelayMs);
}

void PluginMetricsProvider::BrowserChildProcessCrashed(
    const content::ChildProcessData& data,
    int exit_code) {
  GetChildProcessStats(data).process_crashes++;
  RecordCurrentStateWithDelay(kRecordStateDelayMs);
}

void PluginMetricsProvider::BrowserChildProcessKilled(
    const content::ChildProcessData& data,
    int exit_code) {
  // Treat a kill as a crash, since Flash returns STATUS_DEBUGGER_INACTIVE for
  // actual crashes, which is treated as a kill rather than a crash by
  // base::GetTerminationStatus
  GetChildProcessStats(data).process_crashes++;
  RecordCurrentStateWithDelay(kRecordStateDelayMs);
}

bool PluginMetricsProvider::RecordCurrentStateWithDelay(int delay_sec) {
  if (weak_ptr_factory_.HasWeakPtrs())
    return false;

  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&PluginMetricsProvider::RecordCurrentState,
                weak_ptr_factory_.GetWeakPtr()),
                base::TimeDelta::FromMilliseconds(delay_sec));
  return true;
}

bool PluginMetricsProvider::RecordCurrentStateIfPending() {
  if (!weak_ptr_factory_.HasWeakPtrs())
    return false;

  weak_ptr_factory_.InvalidateWeakPtrs();
  RecordCurrentState();
  return true;
}
