1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/permission_context_base.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/prefs/pref_service.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/host_content_settings_map.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/permission_bubble_request_impl.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/permission_context_uma_util.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/permission_queue_controller.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/content_settings/tab_specific_content_settings.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/profiles/profile.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/pref_names.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/content_settings/core/common/permission_request_id.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/web_contents.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
21116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionContextBase::PermissionContextBase(
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    Profile* profile,
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ContentSettingsType permission_type)
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : profile_(profile),
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      permission_type_(permission_type),
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      weak_factory_(this) {
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  permission_queue_controller_.reset(
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new PermissionQueueController(profile_, permission_type_));
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionContextBase::~PermissionContextBase() {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::RequestPermission(
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::WebContents* web_contents,
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const PermissionRequestID& id,
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& requesting_frame,
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool user_gesture,
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BrowserPermissionCallback& callback) {
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DecidePermission(web_contents,
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   id,
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   requesting_frame.GetOrigin(),
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   web_contents->GetLastCommittedURL().GetOrigin(),
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   user_gesture,
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   callback);
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::DecidePermission(
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::WebContents* web_contents,
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const PermissionRequestID& id,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& requesting_origin,
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& embedder_origin,
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool user_gesture,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BrowserPermissionCallback& callback) {
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ContentSetting content_setting =
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      profile_->GetHostContentSettingsMap()->GetContentSetting(
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          requesting_origin, embedder_origin, permission_type_, std::string());
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (content_setting) {
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case CONTENT_SETTING_BLOCK:
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NotifyPermissionSet(id, requesting_origin, embedder_origin,
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          callback, false /* persist */, false /* granted */);
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case CONTENT_SETTING_ALLOW:
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NotifyPermissionSet(id, requesting_origin, embedder_origin,
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          callback, false /* persist */, true /* granted */);
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    default:
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PermissionContextUmaUtil::PermissionRequested(permission_type_);
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (PermissionBubbleManager::Enabled()) {
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PermissionBubbleManager* bubble_manager =
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        PermissionBubbleManager::FromWebContents(web_contents);
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(bubble_manager);
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<PermissionBubbleRequest> request_ptr(
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new PermissionBubbleRequestImpl(
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            requesting_origin,
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            user_gesture,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            permission_type_,
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            base::Bind(&PermissionContextBase::PermissionDecided,
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       weak_factory_.GetWeakPtr(),
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       id,
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       requesting_origin,
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       embedder_origin,
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       callback),
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            base::Bind(&PermissionContextBase::CleanUpBubble,
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       weak_factory_.GetWeakPtr(), id)));
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PermissionBubbleRequest* request = request_ptr.get();
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool inserted = pending_bubbles_.add(
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        id.ToString(), request_ptr.Pass()).second;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(inserted) << "Duplicate id " << id.ToString();
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bubble_manager->AddRequest(request);
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(gbillock): Delete this and the infobar delegate when
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // we're using only bubbles. crbug.com/337458
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GetQueueController()->CreateInfoBarRequest(
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      id,
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      requesting_origin,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      embedder_origin,
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PermissionContextBase::PermissionDecided,
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_factory_.GetWeakPtr(),
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 id,
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 requesting_origin,
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 embedder_origin,
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 callback,
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 // the queue controller takes care of persisting the
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 // permission
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 false));
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::PermissionDecided(
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const PermissionRequestID& id,
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& requesting_origin,
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& embedder_origin,
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BrowserPermissionCallback& callback,
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool persist,
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool allowed) {
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Infobar persistance and its related UMA is tracked on the infobar
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // controller directly.
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (PermissionBubbleManager::Enabled()) {
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (persist) {
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (allowed)
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        PermissionContextUmaUtil::PermissionGranted(permission_type_);
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      else
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        PermissionContextUmaUtil::PermissionDenied(permission_type_);
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else {
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      PermissionContextUmaUtil::PermissionDismissed(permission_type_);
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NotifyPermissionSet(
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      id, requesting_origin, embedder_origin, callback, persist, allowed);
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
147116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPermissionQueueController* PermissionContextBase::GetQueueController() {
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return permission_queue_controller_.get();
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::NotifyPermissionSet(
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const PermissionRequestID& id,
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& requesting_origin,
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& embedder_origin,
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BrowserPermissionCallback& callback,
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool persist,
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool allowed) {
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (persist)
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UpdateContentSetting(requesting_origin, embedder_origin, allowed);
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdateTabContext(id, requesting_origin, allowed);
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(allowed);
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::CleanUpBubble(const PermissionRequestID& id) {
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t success = pending_bubbles_.erase(id.ToString());
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(success == 1) << "Missing request " << id.ToString();
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PermissionContextBase::UpdateContentSetting(
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& requesting_origin,
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& embedder_origin,
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool allowed) {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin());
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(embedder_origin, embedder_origin.GetOrigin());
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ContentSetting content_setting =
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  profile_->GetHostContentSettingsMap()->SetContentSetting(
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ContentSettingsPattern::FromURLNoWildcard(embedder_origin),
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      permission_type_,
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      std::string(),
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content_setting);
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
186