// 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/renderer/pepper/pepper_uma_host.h"

#include <stddef.h>

#include "base/hash/sha1.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "content/public/renderer/pepper_plugin_instance.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "extensions/buildflags/buildflags.h"
#include "media/media_buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

namespace {

const char* const kPredefinedAllowedUMAOrigins[] = {
    "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F",  // see http://crbug.com/317833
    "4EB74897CB187C7633357C2FE832E0AD6A44883A",  // see http://crbug.com/317833
    "9E527CDA9D7C50844E8A5DB964A54A640AE48F98",  // see http://crbug.com/521189
    "DF52618D0B040D8A054D8348D2E84DDEEE5974E7",  // see http://crbug.com/521189
    "269D721F163E587BC53C6F83553BF9CE2BB143CD",  // see http://crbug.com/521189
    "6B55A5329E3F1F30F6032BDB20B2EB4378DBF767",  // see http://crbug.com/521189
    "C449A798C495E6CF7D6AF10162113D564E67AD12",  // see http://crbug.com/521189
    "01E9FFA9A8F3C18271FE91BEE46207F3B81755CC",  // see http://crbug.com/521189
    "97B23E01B2AA064E8332EE43A7A85C628AADC3F2",  // see http://crbug.com/521189
};

const char* const kWhitelistedHistogramPrefixes[] = {
    "22F67DA2061FFC4DC9A4974036348D9C38C22919",  // see http://crbug.com/390221
    "3FEA4650221C5E6C39CF5C5C9F464FF74EAB6CE1",  // see http://crbug.com/521189
};

const base::FilePath::CharType* const kWhitelistedPluginBaseNames[] = {
    ChromeContentClient::kPDFPluginPath,
};

std::string HashPrefix(const std::string& histogram) {
  const std::string id_hash =
      base::SHA1HashString(histogram.substr(0, histogram.find('.')));
  DCHECK_EQ(id_hash.length(), base::kSHA1Length);
  return base::HexEncode(id_hash.c_str(), id_hash.length());
}

}  // namespace

PepperUMAHost::PepperUMAHost(content::RendererPpapiHost* host,
                             PP_Instance instance,
                             PP_Resource resource)
    : ResourceHost(host->GetPpapiHost(), instance, resource),
      document_url_(host->GetDocumentURL(instance)),
      is_plugin_in_process_(host->IsRunningInProcess()) {
  if (host->GetPluginInstance(instance)) {
    plugin_base_name_ =
        host->GetPluginInstance(instance)->GetModulePath().BaseName();
  }

  for (size_t i = 0; i < base::size(kPredefinedAllowedUMAOrigins); ++i)
    allowed_origins_.insert(kPredefinedAllowedUMAOrigins[i]);
  for (size_t i = 0; i < base::size(kWhitelistedHistogramPrefixes); ++i)
    allowed_histogram_prefixes_.insert(kWhitelistedHistogramPrefixes[i]);
  for (size_t i = 0; i < base::size(kWhitelistedPluginBaseNames); ++i)
    allowed_plugin_base_names_.insert(kWhitelistedPluginBaseNames[i]);
}

PepperUMAHost::~PepperUMAHost() {}

int32_t PepperUMAHost::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  PPAPI_BEGIN_MESSAGE_MAP(PepperUMAHost, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomTimes,
                                      OnHistogramCustomTimes)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomCounts,
                                      OnHistogramCustomCounts)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramEnumeration,
                                      OnHistogramEnumeration)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
        PpapiHostMsg_UMA_IsCrashReportingEnabled, OnIsCrashReportingEnabled)
  PPAPI_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

bool PepperUMAHost::IsPluginWhitelisted() {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  return ChromeContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
      document_url_, allowed_origins_);
#else
  return false;
#endif
}

bool PepperUMAHost::IsHistogramAllowed(const std::string& histogram) {
  if (is_plugin_in_process_ &&
      base::StartsWith(histogram, "NaCl.", base::CompareCase::SENSITIVE)) {
    return true;
  }

  if (IsPluginWhitelisted() &&
      base::Contains(allowed_histogram_prefixes_, HashPrefix(histogram))) {
    return true;
  }

  if (base::Contains(allowed_plugin_base_names_, plugin_base_name_.value()))
    return true;

  LOG(ERROR) << "Host or histogram name is not allowed to use the UMA API.";
  return false;
}

#define RETURN_IF_BAD_ARGS(_min, _max, _buckets) \
  do {                                           \
    if (_min >= _max || _buckets <= 1)           \
      return PP_ERROR_BADARGUMENT;               \
  } while (0)

int32_t PepperUMAHost::OnHistogramCustomTimes(
    ppapi::host::HostMessageContext* context,
    const std::string& name,
    int64_t sample,
    int64_t min,
    int64_t max,
    uint32_t bucket_count) {
  if (!IsHistogramAllowed(name)) {
    return PP_ERROR_NOACCESS;
  }
  RETURN_IF_BAD_ARGS(min, max, bucket_count);

  base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
      name,
      base::TimeDelta::FromMilliseconds(min),
      base::TimeDelta::FromMilliseconds(max),
      bucket_count,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  // The histogram can be NULL if it is constructed with bad arguments.  Ignore
  // that data for this API.  An error message will be logged.
  if (counter)
    counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
  return PP_OK;
}

int32_t PepperUMAHost::OnHistogramCustomCounts(
    ppapi::host::HostMessageContext* context,
    const std::string& name,
    int32_t sample,
    int32_t min,
    int32_t max,
    uint32_t bucket_count) {
  if (!IsHistogramAllowed(name)) {
    return PP_ERROR_NOACCESS;
  }
  RETURN_IF_BAD_ARGS(min, max, bucket_count);

  base::HistogramBase* counter = base::Histogram::FactoryGet(
      name,
      min,
      max,
      bucket_count,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  // The histogram can be NULL if it is constructed with bad arguments.  Ignore
  // that data for this API.  An error message will be logged.
  if (counter)
    counter->Add(sample);
  return PP_OK;
}

int32_t PepperUMAHost::OnHistogramEnumeration(
    ppapi::host::HostMessageContext* context,
    const std::string& name,
    int32_t sample,
    int32_t boundary_value) {
  if (!IsHistogramAllowed(name)) {
    return PP_ERROR_NOACCESS;
  }
  RETURN_IF_BAD_ARGS(0, boundary_value, boundary_value + 1);

  base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
      name,
      1,
      boundary_value,
      boundary_value + 1,
      base::HistogramBase::kUmaTargetedHistogramFlag);
  // The histogram can be NULL if it is constructed with bad arguments.  Ignore
  // that data for this API.  An error message will be logged.
  if (counter)
    counter->Add(sample);
  return PP_OK;
}

int32_t PepperUMAHost::OnIsCrashReportingEnabled(
    ppapi::host::HostMessageContext* context) {
  if (!IsPluginWhitelisted())
    return PP_ERROR_NOACCESS;
  bool enabled = false;
  content::RenderThread::Get()->Send(
      new ChromeViewHostMsg_IsCrashReportingEnabled(&enabled));
  if (enabled)
    return PP_OK;
  return PP_ERROR_FAILED;
}
