Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/permissions/permission_context_base.h" | 5 #include "chrome/browser/permissions/permission_context_base.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | |
| 9 #include <queue> | |
| 8 #include <utility> | 10 #include <utility> |
| 9 | 11 |
| 12 #include "base/location.h" | |
| 10 #include "base/logging.h" | 13 #include "base/logging.h" |
| 11 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
| 15 #include "base/rand_util.h" | |
| 16 #include "base/single_thread_task_runner.h" | |
| 12 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/thread_task_runner_handle.h" | |
| 19 #include "base/timer/timer.h" | |
| 13 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 15 #include "chrome/browser/permissions/permission_request_id.h" | 22 #include "chrome/browser/permissions/permission_request_id.h" |
| 16 #include "chrome/browser/permissions/permission_uma_util.h" | 23 #include "chrome/browser/permissions/permission_uma_util.h" |
| 17 #include "chrome/browser/permissions/permission_util.h" | 24 #include "chrome/browser/permissions/permission_util.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
| 27 #include "components/content_settings/core/browser/content_settings_info.h" | |
| 28 #include "components/content_settings/core/browser/content_settings_registry.h" | |
| 20 #include "components/content_settings/core/browser/host_content_settings_map.h" | 29 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 21 #include "components/content_settings/core/browser/website_settings_registry.h" | 30 #include "components/content_settings/core/browser/website_settings_registry.h" |
| 22 #include "components/variations/variations_associated_data.h" | 31 #include "components/variations/variations_associated_data.h" |
| 23 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
| 24 #include "content/public/browser/render_frame_host.h" | 33 #include "content/public/browser/render_frame_host.h" |
| 25 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
| 35 #include "content/public/browser/web_contents_observer.h" | |
| 36 #include "content/public/browser/web_contents_user_data.h" | |
| 26 #include "content/public/common/origin_util.h" | 37 #include "content/public/common/origin_util.h" |
| 27 | 38 |
| 28 #if defined(OS_ANDROID) | 39 #if defined(OS_ANDROID) |
| 29 #include "chrome/browser/permissions/permission_queue_controller.h" | 40 #include "chrome/browser/permissions/permission_queue_controller.h" |
| 30 #else | 41 #else |
| 31 #include "chrome/browser/permissions/permission_bubble_request_impl.h" | 42 #include "chrome/browser/permissions/permission_bubble_request_impl.h" |
| 32 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" | 43 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" |
| 33 #endif | 44 #endif |
| 34 | 45 |
| 46 namespace { | |
| 47 | |
| 48 // At most one of these is attached to each WebContents. | |
| 49 class VisibilityTimerTabHelper | |
| 50 : public content::WebContentsObserver, | |
| 51 public content::WebContentsUserData<VisibilityTimerTabHelper> { | |
| 52 public: | |
| 53 ~VisibilityTimerTabHelper() override {}; | |
| 54 | |
| 55 // Runs |task| after the WebContents has been visible for a consecutive | |
| 56 // duration of at least |visible_delay|. | |
| 57 void PostTaskAfterVisibleDelay(const tracked_objects::Location& from_here, | |
| 58 const base::Closure& task, | |
| 59 base::TimeDelta visible_delay); | |
| 60 | |
| 61 // WebContentsObserver: | |
| 62 void WasShown() override; | |
| 63 void WasHidden() override; | |
| 64 void WebContentsDestroyed() override; | |
| 65 | |
| 66 private: | |
| 67 friend class content::WebContentsUserData<VisibilityTimerTabHelper>; | |
| 68 explicit VisibilityTimerTabHelper(content::WebContents* contents); | |
| 69 | |
| 70 void RunTask(const base::Closure& task); | |
| 71 | |
| 72 bool is_visible_; | |
| 73 std::queue<scoped_ptr<base::Timer>> task_queue_; | |
| 74 | |
| 75 DISALLOW_COPY_AND_ASSIGN(VisibilityTimerTabHelper); | |
| 76 }; | |
| 77 | |
| 78 VisibilityTimerTabHelper::VisibilityTimerTabHelper( | |
| 79 content::WebContents* contents) | |
| 80 : content::WebContentsObserver(contents) { | |
| 81 if (!contents->GetMainFrame()) { | |
| 82 is_visible_ = false; | |
| 83 } else { | |
| 84 switch (contents->GetMainFrame()->GetVisibilityState()) { | |
| 85 case blink::WebPageVisibilityStateHidden: | |
| 86 case blink::WebPageVisibilityStatePrerender: | |
| 87 is_visible_ = false; | |
| 88 break; | |
| 89 case blink::WebPageVisibilityStateVisible: | |
| 90 is_visible_ = true; | |
| 91 break; | |
| 92 } | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 void VisibilityTimerTabHelper::PostTaskAfterVisibleDelay( | |
| 97 const tracked_objects::Location& from_here, | |
| 98 const base::Closure& task, | |
| 99 base::TimeDelta visible_delay) { | |
| 100 // Safe to use Unretained, as destroying this will destroy task_queue_, hence | |
| 101 // cancelling all timers. | |
| 102 task_queue_.push(make_scoped_ptr(new base::Timer( | |
| 103 from_here, visible_delay, base::Bind(&VisibilityTimerTabHelper::RunTask, | |
| 104 base::Unretained(this), task), | |
| 105 false /* is_repeating */))); | |
| 106 DCHECK(!task_queue_.back()->IsRunning()); | |
| 107 if (is_visible_ && task_queue_.size() == 1) | |
| 108 task_queue_.front()->Reset(); | |
| 109 } | |
| 110 | |
| 111 void VisibilityTimerTabHelper::WasShown() { | |
| 112 if (!is_visible_ && !task_queue_.empty()) | |
| 113 task_queue_.front()->Reset(); | |
| 114 is_visible_ = true; | |
| 115 } | |
| 116 | |
| 117 void VisibilityTimerTabHelper::WasHidden() { | |
| 118 if (is_visible_ && !task_queue_.empty()) | |
| 119 task_queue_.front()->Stop(); | |
| 120 is_visible_ = false; | |
| 121 } | |
| 122 | |
| 123 void VisibilityTimerTabHelper::WebContentsDestroyed() { | |
| 124 // Delete ourselves, to avoid running tasks after WebContents is destroyed. | |
| 125 web_contents()->RemoveUserData(UserDataKey()); | |
| 126 // |this| has been deleted now. | |
| 127 } | |
| 128 | |
| 129 void VisibilityTimerTabHelper::RunTask(const base::Closure& task) { | |
| 130 DCHECK(is_visible_); | |
| 131 task.Run(); | |
| 132 task_queue_.pop(); | |
| 133 if (!task_queue_.empty()) { | |
| 134 task_queue_.front()->Reset(); | |
| 135 return; | |
| 136 } | |
| 137 web_contents()->RemoveUserData(UserDataKey()); | |
| 138 // |this| has been deleted now. | |
| 139 } | |
| 140 | |
| 141 } // namespace | |
| 142 | |
| 143 DEFINE_WEB_CONTENTS_USER_DATA_KEY(VisibilityTimerTabHelper); | |
| 144 | |
| 35 // static | 145 // static |
| 36 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = | 146 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = |
| 37 "PermissionsKillSwitch"; | 147 "PermissionsKillSwitch"; |
| 38 // static | 148 // static |
| 39 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = | 149 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = |
| 40 "blocked"; | 150 "blocked"; |
| 41 | 151 |
| 42 PermissionContextBase::PermissionContextBase( | 152 PermissionContextBase::PermissionContextBase( |
| 43 Profile* profile, | 153 Profile* profile, |
| 44 const content::PermissionType permission_type, | 154 const content::PermissionType permission_type, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 | 272 |
| 163 void PermissionContextBase::DecidePermission( | 273 void PermissionContextBase::DecidePermission( |
| 164 content::WebContents* web_contents, | 274 content::WebContents* web_contents, |
| 165 const PermissionRequestID& id, | 275 const PermissionRequestID& id, |
| 166 const GURL& requesting_origin, | 276 const GURL& requesting_origin, |
| 167 const GURL& embedding_origin, | 277 const GURL& embedding_origin, |
| 168 bool user_gesture, | 278 bool user_gesture, |
| 169 const BrowserPermissionCallback& callback) { | 279 const BrowserPermissionCallback& callback) { |
| 170 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 280 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 171 | 281 |
| 282 // Some permissions are always denied in incognito. To prevent sites from | |
|
mlamouri (slow - plz ping)
2016/01/11 16:03:57
Today, that's only Push, right? Do we have plans t
johnme
2016/01/11 16:29:20
Push and notifications. We probably won't add any
| |
| 283 // using these to detect whether incognito mode is active, we deny after a | |
| 284 // random time delay, to simulate a user clicking a bubble/infobar. | |
| 285 if (profile()->IsOffTheRecord()) { | |
| 286 const content_settings::ContentSettingsInfo* info = | |
| 287 content_settings::ContentSettingsRegistry::GetInstance()->Get( | |
| 288 content_settings_type_); | |
|
mlamouri (slow - plz ping)
2016/01/11 16:03:57
Why are we getting the information from content se
johnme
2016/01/11 16:29:20
I could move this block of code to a NotificationP
johnme
2016/01/12 18:04:52
Ok, I've moved all this code from PermissionContex
| |
| 289 if (info && | |
| 290 info->incognito_behavior() == content_settings::ContentSettingsInfo:: | |
| 291 DENY_IN_INCOGNITO_AFTER_DELAY) { | |
| 292 // Random number of seconds in the range [1.0, 2.0). | |
| 293 double delay_seconds = 1.0 + 1.0 * base::RandDouble(); | |
| 294 VisibilityTimerTabHelper::CreateForWebContents(web_contents); | |
| 295 VisibilityTimerTabHelper::FromWebContents(web_contents) | |
| 296 ->PostTaskAfterVisibleDelay( | |
| 297 FROM_HERE, | |
| 298 base::Bind(&PermissionContextBase::NotifyPermissionSet, | |
| 299 weak_factory_.GetWeakPtr(), id, requesting_origin, | |
| 300 embedding_origin, callback, true /* persist */, | |
| 301 CONTENT_SETTING_BLOCK), | |
| 302 base::TimeDelta::FromSecondsD(delay_seconds)); | |
| 303 return; | |
| 304 } | |
| 305 } | |
| 306 | |
| 172 #if !defined(OS_ANDROID) | 307 #if !defined(OS_ANDROID) |
| 173 PermissionBubbleManager* bubble_manager = | 308 PermissionBubbleManager* bubble_manager = |
| 174 PermissionBubbleManager::FromWebContents(web_contents); | 309 PermissionBubbleManager::FromWebContents(web_contents); |
| 175 // TODO(felt): sometimes |bubble_manager| is null. This check is meant to | 310 // TODO(felt): sometimes |bubble_manager| is null. This check is meant to |
| 176 // prevent crashes. See crbug.com/457091. | 311 // prevent crashes. See crbug.com/457091. |
| 177 if (!bubble_manager) | 312 if (!bubble_manager) |
| 178 return; | 313 return; |
| 179 scoped_ptr<PermissionBubbleRequest> request_ptr( | 314 scoped_ptr<PermissionBubbleRequest> request_ptr( |
| 180 new PermissionBubbleRequestImpl( | 315 new PermissionBubbleRequestImpl( |
| 181 requesting_origin, user_gesture, permission_type_, | 316 requesting_origin, user_gesture, permission_type_, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 content_settings_type_, std::string(), content_setting); | 420 content_settings_type_, std::string(), content_setting); |
| 286 } | 421 } |
| 287 | 422 |
| 288 bool PermissionContextBase::IsPermissionKillSwitchOn() const { | 423 bool PermissionContextBase::IsPermissionKillSwitchOn() const { |
| 289 const std::string param = variations::GetVariationParamValue( | 424 const std::string param = variations::GetVariationParamValue( |
| 290 kPermissionsKillSwitchFieldStudy, | 425 kPermissionsKillSwitchFieldStudy, |
| 291 PermissionUtil::GetPermissionString(permission_type_)); | 426 PermissionUtil::GetPermissionString(permission_type_)); |
| 292 | 427 |
| 293 return param == kPermissionsKillSwitchBlockedValue; | 428 return param == kPermissionsKillSwitchBlockedValue; |
| 294 } | 429 } |
| OLD | NEW |