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 |