<commit_before>// 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/content_settings/permission_context_base.h"

#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/content_settings/permission_bubble_request_impl.h"
#include "chrome/browser/content_settings/permission_context_uma_util.h"
#include "chrome/browser/content_settings/permission_queue_controller.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/permission_request_id.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"

PermissionContextBase::PermissionContextBase(
    Profile* profile,
    const ContentSettingsType permission_type)
    : profile_(profile),
      permission_type_(permission_type),
      weak_factory_(this) {
  permission_queue_controller_.reset(
      new PermissionQueueController(profile_, permission_type_));
}

PermissionContextBase::~PermissionContextBase() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

void PermissionContextBase::RequestPermission(
    content::WebContents* web_contents,
    const PermissionRequestID& id,
    const GURL& requesting_frame,
    bool user_gesture,
    const BrowserPermissionCallback& callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  DecidePermission(web_contents,
                   id,
                   requesting_frame.GetOrigin(),
                   web_contents->GetLastCommittedURL().GetOrigin(),
                   user_gesture,
                   callback);
}

ContentSetting PermissionContextBase::GetPermissionStatus(
    const GURL& requesting_origin,
    const GURL& embedding_origin) const {
  return profile_->GetHostContentSettingsMap()->GetContentSetting(
      requesting_origin, embedding_origin, permission_type_, std::string());
}

void PermissionContextBase::ResetPermission(
    const GURL& requesting_origin,
    const GURL& embedding_origin) {
  profile_->GetHostContentSettingsMap()->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
      ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
      permission_type_, std::string(), CONTENT_SETTING_DEFAULT);
}

void PermissionContextBase::CancelPermissionRequest(
    content::WebContents* web_contents,
    const PermissionRequestID& id) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (PermissionBubbleManager::Enabled()) {
    PermissionBubbleRequest* cancelling =
        pending_bubbles_.get(id.ToString());
    if (cancelling != NULL && web_contents != NULL &&
        PermissionBubbleManager::FromWebContents(web_contents) != NULL) {
      PermissionBubbleManager::FromWebContents(web_contents)->
          CancelRequest(cancelling);
    }
    return;
  }

  GetQueueController()->CancelInfoBarRequest(id);
}

void PermissionContextBase::DecidePermission(
    content::WebContents* web_contents,
    const PermissionRequestID& id,
    const GURL& requesting_origin,
    const GURL& embedding_origin,
    bool user_gesture,
    const BrowserPermissionCallback& callback) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) {
    DVLOG(1)
        << "Attempt to use " << content_settings::GetTypeName(permission_type_)
        << " from an invalid URL: " << requesting_origin
        << "," << embedding_origin
        << " (" << content_settings::GetTypeName(permission_type_)
        << " is not supported in popups)";
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, CONTENT_SETTING_BLOCK);
    return;
  }

  // The Web MIDI SYSEX API is only available to secure origins.
  if (permission_type_ == CONTENT_SETTINGS_TYPE_MIDI_SYSEX &&
      !content::IsOriginSecure(requesting_origin)) {
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, CONTENT_SETTING_BLOCK);
    return;
  }

  ContentSetting content_setting =
      profile_->GetHostContentSettingsMap()
          ->GetContentSettingAndMaybeUpdateLastUsage(
              requesting_origin, embedding_origin, permission_type_,
              std::string());

  if (content_setting == CONTENT_SETTING_ALLOW ||
      content_setting == CONTENT_SETTING_BLOCK) {
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, content_setting);
    return;
  }

  PermissionContextUmaUtil::PermissionRequested(
      permission_type_, requesting_origin);

  if (PermissionBubbleManager::Enabled()) {
    if (pending_bubbles_.get(id.ToString()) != NULL)
      return;
    PermissionBubbleManager* bubble_manager =
        PermissionBubbleManager::FromWebContents(web_contents);
    // TODO(mlamouri): sometimes |bubble_manager| is null. This check is meant
    // to prevent crashes. See bug 457091.
    if (!bubble_manager)
      return;
    scoped_ptr<PermissionBubbleRequest> request_ptr(
        new PermissionBubbleRequestImpl(
            requesting_origin, user_gesture, permission_type_,
            profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
            base::Bind(&PermissionContextBase::PermissionDecided,
                       weak_factory_.GetWeakPtr(), id, requesting_origin,
                       embedding_origin, callback),
            base::Bind(&PermissionContextBase::CleanUpBubble,
                       weak_factory_.GetWeakPtr(), id)));
    PermissionBubbleRequest* request = request_ptr.get();

    bool inserted = pending_bubbles_.add(
        id.ToString(), request_ptr.Pass()).second;
    DCHECK(inserted) << "Duplicate id " << id.ToString();
    bubble_manager->AddRequest(request);
    return;
  }

  // TODO(gbillock): Delete this and the infobar delegate when
  // we're using only bubbles. crbug.com/337458
  GetQueueController()->CreateInfoBarRequest(
      id, requesting_origin, embedding_origin,
      base::Bind(&PermissionContextBase::PermissionDecided,
                 weak_factory_.GetWeakPtr(), id, requesting_origin,
                 embedding_origin, callback,
                 // the queue controller takes care of persisting the
                 // permission
                 false));
}

void PermissionContextBase::PermissionDecided(
    const PermissionRequestID& id,
    const GURL& requesting_origin,
    const GURL& embedding_origin,
    const BrowserPermissionCallback& callback,
    bool persist,
    ContentSetting content_setting) {
  // Infobar persistance and its related UMA is tracked on the infobar
  // controller directly.
  if (PermissionBubbleManager::Enabled()) {
    if (persist) {
      DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
             content_setting == CONTENT_SETTING_BLOCK);
      if (CONTENT_SETTING_ALLOW)
        PermissionContextUmaUtil::PermissionGranted(permission_type_,
                                                    requesting_origin);<commit_msg>Fix UMA reporting for permission granted stats with bubbles<commit_after>// 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/content_settings/permission_context_base.h"

#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/content_settings/permission_bubble_request_impl.h"
#include "chrome/browser/content_settings/permission_context_uma_util.h"
#include "chrome/browser/content_settings/permission_queue_controller.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/permission_request_id.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"

PermissionContextBase::PermissionContextBase(
    Profile* profile,
    const ContentSettingsType permission_type)
    : profile_(profile),
      permission_type_(permission_type),
      weak_factory_(this) {
  permission_queue_controller_.reset(
      new PermissionQueueController(profile_, permission_type_));
}

PermissionContextBase::~PermissionContextBase() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

void PermissionContextBase::RequestPermission(
    content::WebContents* web_contents,
    const PermissionRequestID& id,
    const GURL& requesting_frame,
    bool user_gesture,
    const BrowserPermissionCallback& callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  DecidePermission(web_contents,
                   id,
                   requesting_frame.GetOrigin(),
                   web_contents->GetLastCommittedURL().GetOrigin(),
                   user_gesture,
                   callback);
}

ContentSetting PermissionContextBase::GetPermissionStatus(
    const GURL& requesting_origin,
    const GURL& embedding_origin) const {
  return profile_->GetHostContentSettingsMap()->GetContentSetting(
      requesting_origin, embedding_origin, permission_type_, std::string());
}

void PermissionContextBase::ResetPermission(
    const GURL& requesting_origin,
    const GURL& embedding_origin) {
  profile_->GetHostContentSettingsMap()->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
      ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
      permission_type_, std::string(), CONTENT_SETTING_DEFAULT);
}

void PermissionContextBase::CancelPermissionRequest(
    content::WebContents* web_contents,
    const PermissionRequestID& id) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (PermissionBubbleManager::Enabled()) {
    PermissionBubbleRequest* cancelling =
        pending_bubbles_.get(id.ToString());
    if (cancelling != NULL && web_contents != NULL &&
        PermissionBubbleManager::FromWebContents(web_contents) != NULL) {
      PermissionBubbleManager::FromWebContents(web_contents)->
          CancelRequest(cancelling);
    }
    return;
  }

  GetQueueController()->CancelInfoBarRequest(id);
}

void PermissionContextBase::DecidePermission(
    content::WebContents* web_contents,
    const PermissionRequestID& id,
    const GURL& requesting_origin,
    const GURL& embedding_origin,
    bool user_gesture,
    const BrowserPermissionCallback& callback) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) {
    DVLOG(1)
        << "Attempt to use " << content_settings::GetTypeName(permission_type_)
        << " from an invalid URL: " << requesting_origin
        << "," << embedding_origin
        << " (" << content_settings::GetTypeName(permission_type_)
        << " is not supported in popups)";
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, CONTENT_SETTING_BLOCK);
    return;
  }

  // The Web MIDI SYSEX API is only available to secure origins.
  if (permission_type_ == CONTENT_SETTINGS_TYPE_MIDI_SYSEX &&
      !content::IsOriginSecure(requesting_origin)) {
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, CONTENT_SETTING_BLOCK);
    return;
  }

  ContentSetting content_setting =
      profile_->GetHostContentSettingsMap()
          ->GetContentSettingAndMaybeUpdateLastUsage(
              requesting_origin, embedding_origin, permission_type_,
              std::string());

  if (content_setting == CONTENT_SETTING_ALLOW ||
      content_setting == CONTENT_SETTING_BLOCK) {
    NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
                        false /* persist */, content_setting);
    return;
  }

  PermissionContextUmaUtil::PermissionRequested(
      permission_type_, requesting_origin);

  if (PermissionBubbleManager::Enabled()) {
    if (pending_bubbles_.get(id.ToString()) != NULL)
      return;
    PermissionBubbleManager* bubble_manager =
        PermissionBubbleManager::FromWebContents(web_contents);
    // TODO(mlamouri): sometimes |bubble_manager| is null. This check is meant
    // to prevent crashes. See bug 457091.
    if (!bubble_manager)
      return;
    scoped_ptr<PermissionBubbleRequest> request_ptr(
        new PermissionBubbleRequestImpl(
            requesting_origin, user_gesture, permission_type_,
            profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
            base::Bind(&PermissionContextBase::PermissionDecided,
                       weak_factory_.GetWeakPtr(), id, requesting_origin,
                       embedding_origin, callback),
            base::Bind(&PermissionContextBase::CleanUpBubble,
                       weak_factory_.GetWeakPtr(), id)));
    PermissionBubbleRequest* request = request_ptr.get();

    bool inserted = pending_bubbles_.add(
        id.ToString(), request_ptr.Pass()).second;
    DCHECK(inserted) << "Duplicate id " << id.ToString();
    bubble_manager->AddRequest(request);
    return;
  }

  // TODO(gbillock): Delete this and the infobar delegate when
  // we're using only bubbles. crbug.com/337458
  GetQueueController()->CreateInfoBarRequest(
      id, requesting_origin, embedding_origin,
      base::Bind(&PermissionContextBase::PermissionDecided,
                 weak_factory_.GetWeakPtr(), id, requesting_origin,
                 embedding_origin, callback,
                 // the queue controller takes care of persisting the
                 // permission
                 false));
}

void PermissionContextBase::PermissionDecided(
    const PermissionRequestID& id,
    const GURL& requesting_origin,
    const GURL& embedding_origin,
    const BrowserPermissionCallback& callback,
    bool persist,
    ContentSetting content_setting) {
  // Infobar persistance and its related UMA is tracked on the infobar
  // controller directly.
  if (PermissionBubbleManager::Enabled()) {
    if (persist) {
      DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
             content_setting == CONTENT_SETTING_BLOCK);
      if (content_setting == CONTENT_SETTING_ALLOW)
        PermissionContextUmaUtil::PermissionGranted(permission_type_,
                                                    requesting_origin);
{'fraction_non_alphanumeric': 0.09547237550694768, 'fraction_numerical': 0.0022604879994681205, 'mean_word_length': 3.8506933247339568, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 31, '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': '2766061', 'n_tokens_mistral': 4146, 'n_tokens_neox': 3965, 'n_words': 760}