Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: chrome/browser/media/protected_media_identifier_permission_context.cc

Issue 1001723002: media: Refactor PlatformVerificationFlow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix unittest Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/media/protected_media_identifier_permission_context.h" 5 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
6 6
7 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 8 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
9 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/common/pref_names.h" 10 #include "chrome/common/pref_names.h"
11 #include "components/content_settings/core/common/permission_request_id.h" 11 #include "components/content_settings/core/common/permission_request_id.h"
12 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/user_metrics.h"
13 #include "content/public/browser/web_contents.h" 14 #include "content/public/browser/web_contents.h"
14 15
15 #if defined(OS_CHROMEOS) 16 #if defined(OS_CHROMEOS)
16 #include <utility> 17 #include <utility>
17 18
18 #include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" 19 #include "chrome/browser/chromeos/attestation/platform_verification_dialog.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h" 20 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chromeos/settings/cros_settings_names.h" 21 #include "chromeos/settings/cros_settings_names.h"
22 #include "components/pref_registry/pref_registry_syncable.h"
23 #include "components/user_prefs/user_prefs.h"
21 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
22 25
23 using chromeos::attestation::PlatformVerificationDialog; 26 using chromeos::attestation::PlatformVerificationDialog;
24 using chromeos::attestation::PlatformVerificationFlow;
25 #endif 27 #endif
26 28
27 ProtectedMediaIdentifierPermissionContext:: 29 ProtectedMediaIdentifierPermissionContext::
28 ProtectedMediaIdentifierPermissionContext(Profile* profile) 30 ProtectedMediaIdentifierPermissionContext(Profile* profile)
29 : PermissionContextBase(profile, 31 : PermissionContextBase(profile,
30 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) 32 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER)
31 #if defined(OS_CHROMEOS) 33 #if defined(OS_CHROMEOS)
32 , 34 ,
33 weak_factory_(this) 35 weak_factory_(this)
34 #endif 36 #endif
35 { 37 {
36 } 38 }
37 39
38 ProtectedMediaIdentifierPermissionContext:: 40 ProtectedMediaIdentifierPermissionContext::
39 ~ProtectedMediaIdentifierPermissionContext() { 41 ~ProtectedMediaIdentifierPermissionContext() {
40 } 42 }
41 43
44 #if defined(OS_CHROMEOS)
45 // static
46 void ProtectedMediaIdentifierPermissionContext::RegisterProfilePrefs(
47 user_prefs::PrefRegistrySyncable* prefs) {
48 prefs->RegisterBooleanPref(prefs::kRAConsentGranted,
49 false, // Default value.
50 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
51 }
52 #endif
53
42 void ProtectedMediaIdentifierPermissionContext::RequestPermission( 54 void ProtectedMediaIdentifierPermissionContext::RequestPermission(
43 content::WebContents* web_contents, 55 content::WebContents* web_contents,
44 const PermissionRequestID& id, 56 const PermissionRequestID& id,
45 const GURL& requesting_origin, 57 const GURL& requesting_origin,
46 bool user_gesture, 58 bool user_gesture,
47 const BrowserPermissionCallback& callback) { 59 const BrowserPermissionCallback& callback) {
48 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 60 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
49 61
50 GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); 62 GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
51 63
64 DVLOG(1) << __FUNCTION__ << ": (" << requesting_origin.spec() << ", "
65 << embedding_origin.spec() << ")";
66
52 if (!requesting_origin.is_valid() || !embedding_origin.is_valid() || 67 if (!requesting_origin.is_valid() || !embedding_origin.is_valid() ||
53 !IsProtectedMediaIdentifierEnabled()) { 68 !IsProtectedMediaIdentifierEnabled()) {
54 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, 69 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
55 false /* persist */, CONTENT_SETTING_BLOCK); 70 false /* persist */, CONTENT_SETTING_BLOCK);
56 return; 71 return;
57 } 72 }
58 73
59 #if defined(OS_CHROMEOS) 74 #if defined(OS_CHROMEOS)
60 // On ChromeOS, we don't use PermissionContextBase::RequestPermission() which 75 ContentSetting content_setting = PermissionContextBase::GetPermissionStatus(
61 // uses the standard permission infobar/bubble UI. See http://crbug.com/454847 76 requesting_origin, embedding_origin);
62 // Instead, we check the content setting and show the existing platform 77 if (content_setting == CONTENT_SETTING_BLOCK) {
63 // verification UI.
64 // TODO(xhwang): Remove when http://crbug.com/454847 is fixed.
65 ContentSetting content_setting =
66 GetPermissionStatus(requesting_origin, embedding_origin);
67
68 if (content_setting == CONTENT_SETTING_ALLOW ||
69 content_setting == CONTENT_SETTING_BLOCK) {
70 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, 78 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
71 false /* persist */, content_setting); 79 false /* persist */, CONTENT_SETTING_BLOCK);
72 return; 80 return;
73 } 81 }
74 82
83 // Consent required if user has never given consent for this origin, or if
84 // user has never given consent to attestation for content protection on this
85 // device.
86 bool consent_required =
87 content_setting != CONTENT_SETTING_ALLOW ||
88 !profile()->GetPrefs()->GetBoolean(prefs::kRAConsentGranted);
89
90 if (!consent_required) {
ddorwin 2015/03/12 03:58:12 nit: All the negative logic is a bit confusing. Pe
xhwang 2015/03/12 17:35:26 Done.
91 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
92 false /* persist */, CONTENT_SETTING_ALLOW);
93 return;
94 }
95
75 // Since the dialog is modal, we only support one prompt per |web_contents|. 96 // Since the dialog is modal, we only support one prompt per |web_contents|.
76 // Reject the new one if there is already one pending. See 97 // Reject the new one if there is already one pending. See
77 // http://crbug.com/447005 98 // http://crbug.com/447005
78 if (pending_requests_.count(web_contents)) { 99 if (pending_requests_.count(web_contents)) {
79 callback.Run(CONTENT_SETTING_DEFAULT); 100 callback.Run(CONTENT_SETTING_DEFAULT);
80 return; 101 return;
81 } 102 }
82 103
104 // On ChromeOS, we don't use PermissionContextBase::RequestPermission() which
105 // uses the standard permission infobar/bubble UI. See http://crbug.com/454847
106 // Instead, we check the content setting and show the existing platform
ddorwin 2015/03/12 03:58:12 ... setting (above) and ... ?
xhwang 2015/03/12 17:35:27 Done.
107 // verification UI.
108 // TODO(xhwang): Remove when http://crbug.com/454847 is fixed.
83 views::Widget* widget = PlatformVerificationDialog::ShowDialog( 109 views::Widget* widget = PlatformVerificationDialog::ShowDialog(
84 web_contents, requesting_origin, 110 web_contents, requesting_origin,
85 base::Bind(&ProtectedMediaIdentifierPermissionContext:: 111 base::Bind(&ProtectedMediaIdentifierPermissionContext::
86 OnPlatformVerificationResult, 112 OnPlatformVerificationConsentResponse,
87 weak_factory_.GetWeakPtr(), web_contents, id, 113 weak_factory_.GetWeakPtr(), web_contents, id,
88 requesting_origin, embedding_origin, callback)); 114 requesting_origin, embedding_origin, callback));
89 pending_requests_.insert( 115 pending_requests_.insert(
90 std::make_pair(web_contents, std::make_pair(widget, id))); 116 std::make_pair(web_contents, std::make_pair(widget, id)));
91 #else 117 #else
92 PermissionContextBase::RequestPermission(web_contents, id, requesting_origin, 118 PermissionContextBase::RequestPermission(web_contents, id, requesting_origin,
93 user_gesture, callback); 119 user_gesture, callback);
94 #endif 120 #endif
95 } 121 }
96 122
97 ContentSetting ProtectedMediaIdentifierPermissionContext::GetPermissionStatus( 123 ContentSetting ProtectedMediaIdentifierPermissionContext::GetPermissionStatus(
98 const GURL& requesting_origin, 124 const GURL& requesting_origin,
99 const GURL& embedding_origin) const { 125 const GURL& embedding_origin) const {
126 DVLOG(1) << __FUNCTION__ << ": (" << requesting_origin.spec() << ", "
127 << embedding_origin.spec() << ")";
128
100 if (!IsProtectedMediaIdentifierEnabled()) 129 if (!IsProtectedMediaIdentifierEnabled())
101 return CONTENT_SETTING_BLOCK; 130 return CONTENT_SETTING_BLOCK;
102 131
132 #if defined(OS_CHROMEOS)
133 // Block if user never granted RA consent on this device. It's possible that
134 // user dismissed the dialog triggered by RequestPermission() and the content
135 // setting is set to "allow" by server sync. In this case, we should block.
136 if (!profile()->GetPrefs()->GetBoolean(prefs::kRAConsentGranted)) {
137 DVLOG(1) << "RA consent never granted on this device.";
138 return CONTENT_SETTING_BLOCK;
ddorwin 2015/03/12 03:58:12 Why do we block in this case rather than return NO
xhwang 2015/03/12 17:35:26 Good point. Changed to ASK.
139 }
140 #endif
141
103 return PermissionContextBase::GetPermissionStatus(requesting_origin, 142 return PermissionContextBase::GetPermissionStatus(requesting_origin,
104 embedding_origin); 143 embedding_origin);
105 } 144 }
106 145
107 void ProtectedMediaIdentifierPermissionContext::CancelPermissionRequest( 146 void ProtectedMediaIdentifierPermissionContext::CancelPermissionRequest(
108 content::WebContents* web_contents, 147 content::WebContents* web_contents,
109 const PermissionRequestID& id) { 148 const PermissionRequestID& id) {
110 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 149 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
111 150
112 #if defined(OS_CHROMEOS) 151 #if defined(OS_CHROMEOS)
113 PendingRequestMap::iterator request = pending_requests_.find(web_contents); 152 PendingRequestMap::iterator request = pending_requests_.find(web_contents);
114 if (request == pending_requests_.end() || !request->second.second.Equals(id)) 153 if (request == pending_requests_.end() || !request->second.second.Equals(id))
115 return; 154 return;
116 155
117 // Close the |widget_|. OnPlatformVerificationResult() will be fired 156 // Close the |widget_|. OnPlatformVerificationConsentResponse() will be fired
118 // during this process, but since |web_contents| is removed from 157 // during this process, but since |web_contents| is removed from
119 // |pending_requests_|, the callback will simply be dropped. 158 // |pending_requests_|, the callback will simply be dropped.
120 views::Widget* widget = request->second.first; 159 views::Widget* widget = request->second.first;
121 pending_requests_.erase(request); 160 pending_requests_.erase(request);
122 widget->Close(); 161 widget->Close();
123 #else 162 #else
124 PermissionContextBase::CancelPermissionRequest(web_contents, id); 163 PermissionContextBase::CancelPermissionRequest(web_contents, id);
125 #endif 164 #endif
126 } 165 }
127 166
(...skipping 10 matching lines...) Expand all
138 if (content_settings) { 177 if (content_settings) {
139 content_settings->OnProtectedMediaIdentifierPermissionSet( 178 content_settings->OnProtectedMediaIdentifierPermissionSet(
140 requesting_frame.GetOrigin(), allowed); 179 requesting_frame.GetOrigin(), allowed);
141 } 180 }
142 } 181 }
143 182
144 // TODO(xhwang): We should consolidate the "protected content" related pref 183 // TODO(xhwang): We should consolidate the "protected content" related pref
145 // across platforms. 184 // across platforms.
146 bool ProtectedMediaIdentifierPermissionContext:: 185 bool ProtectedMediaIdentifierPermissionContext::
147 IsProtectedMediaIdentifierEnabled() const { 186 IsProtectedMediaIdentifierEnabled() const {
148 bool enabled = false;
149
150 #if defined(OS_ANDROID) 187 #if defined(OS_ANDROID)
151 enabled = profile()->GetPrefs()->GetBoolean( 188 if (!profile()->GetPrefs()->GetBoolean(
152 prefs::kProtectedMediaIdentifierEnabled); 189 prefs::kProtectedMediaIdentifierEnabled)) {
190 DVLOG(1) << "Protected media identifier disabled by a user master switch.";
191 return false;
192 }
153 #endif 193 #endif
154 194
155 #if defined(OS_CHROMEOS) 195 #if defined(OS_CHROMEOS)
ddorwin 2015/03/12 03:58:12 Should this be #elif?
xhwang 2015/03/12 17:35:26 Done.
156 // This could be disabled by the device policy. 196 // Platform verification is not allowed in incognito or guest mode.
197 if (profile()->IsOffTheRecord() || profile()->IsGuestSession()) {
198 DVLOG(1) << "Protected media identifier disabled in incognito or guest "
199 "mode.";
200 return false;
201 }
202
203 // This could be disabled by user's master switch or by the device policy.
ddorwin 2015/03/12 03:58:12 It appears we check in the opposite order. If so,
xhwang 2015/03/12 17:35:26 Done.
157 bool enabled_for_device = false; 204 bool enabled_for_device = false;
158 enabled = chromeos::CrosSettings::Get()->GetBoolean( 205 if (!chromeos::CrosSettings::Get()->GetBoolean(
159 chromeos::kAttestationForContentProtectionEnabled, 206 chromeos::kAttestationForContentProtectionEnabled,
160 &enabled_for_device) && 207 &enabled_for_device) ||
161 enabled_for_device && 208 !enabled_for_device ||
162 profile()->GetPrefs()->GetBoolean(prefs::kEnableDRM); 209 !profile()->GetPrefs()->GetBoolean(prefs::kEnableDRM)) {
210 DVLOG(1) << "Protected media identifier disabled by the user or by device "
211 "policy.";
212 return false;
213 }
163 #endif 214 #endif
164 215
165 DVLOG_IF(1, !enabled) 216 return true;
166 << "Protected media identifier disabled by the user or by device policy.";
167 return enabled;
168 } 217 }
169 218
170 #if defined(OS_CHROMEOS) 219 #if defined(OS_CHROMEOS)
171 void ProtectedMediaIdentifierPermissionContext::OnPlatformVerificationResult( 220 static void RecordRAConsentGranted(content::WebContents* web_contents) {
172 content::WebContents* web_contents, 221 PrefService* pref_service =
173 const PermissionRequestID& id, 222 user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
174 const GURL& requesting_origin, 223 if (!pref_service) {
175 const GURL& embedding_origin, 224 LOG(ERROR) << "Failed to get user prefs.";
176 const BrowserPermissionCallback& callback, 225 return;
177 chromeos::attestation::PlatformVerificationFlow::ConsentResponse response) { 226 }
227 pref_service->SetBoolean(prefs::kRAConsentGranted, true);
228 }
229
230 void ProtectedMediaIdentifierPermissionContext::
231 OnPlatformVerificationConsentResponse(
232 content::WebContents* web_contents,
233 const PermissionRequestID& id,
234 const GURL& requesting_origin,
235 const GURL& embedding_origin,
236 const BrowserPermissionCallback& callback,
237 chromeos::attestation::PlatformVerificationDialog::ConsentResponse
238 response) {
178 // The request may have been canceled. Drop the callback in that case. 239 // The request may have been canceled. Drop the callback in that case.
179 PendingRequestMap::iterator request = pending_requests_.find(web_contents); 240 PendingRequestMap::iterator request = pending_requests_.find(web_contents);
180 if (request == pending_requests_.end()) 241 if (request == pending_requests_.end())
181 return; 242 return;
182 243
183 DCHECK(request->second.second.Equals(id)); 244 DCHECK(request->second.second.Equals(id));
184 pending_requests_.erase(request); 245 pending_requests_.erase(request);
185 246
186 ContentSetting content_setting = CONTENT_SETTING_DEFAULT; 247 ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
187 bool persist = false; // Whether the ContentSetting should be saved. 248 bool persist = false; // Whether the ContentSetting should be saved.
188 switch (response) { 249 switch (response) {
189 case PlatformVerificationFlow::CONSENT_RESPONSE_NONE: 250 case PlatformVerificationDialog::CONSENT_RESPONSE_NONE:
190 content_setting = CONTENT_SETTING_DEFAULT; 251 content_setting = CONTENT_SETTING_DEFAULT;
191 persist = false; 252 persist = false;
192 break; 253 break;
193 case PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW: 254 case PlatformVerificationDialog::CONSENT_RESPONSE_ALLOW:
255 VLOG(1) << "Platform verification accepted by user.";
256 content::RecordAction(
257 base::UserMetricsAction("PlatformVerificationAccepted"));
ddorwin 2015/03/12 03:58:12 Should we record None too? Would be interesting to
xhwang 2015/03/12 17:35:26 This and PlatformVerificationRejected are actually
Darren Krahn 2015/03/13 22:47:11 I don't care either way. IIUC, user actions are ty
258 RecordRAConsentGranted(web_contents);
194 content_setting = CONTENT_SETTING_ALLOW; 259 content_setting = CONTENT_SETTING_ALLOW;
195 persist = true; 260 persist = true;
196 break; 261 break;
197 case PlatformVerificationFlow::CONSENT_RESPONSE_DENY: 262 case PlatformVerificationDialog::CONSENT_RESPONSE_DENY:
263 VLOG(1) << "Platform verification denied by user.";
264 content::RecordAction(
265 base::UserMetricsAction("PlatformVerificationRejected"));
198 content_setting = CONTENT_SETTING_BLOCK; 266 content_setting = CONTENT_SETTING_BLOCK;
199 persist = true; 267 persist = true;
200 break; 268 break;
201 } 269 }
202 270
203 NotifyPermissionSet( 271 NotifyPermissionSet(
204 id, requesting_origin, embedding_origin, callback, 272 id, requesting_origin, embedding_origin, callback,
205 persist, content_setting); 273 persist, content_setting);
206 } 274 }
207 #endif 275 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698