OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/permissions/permission_infobar_request.h" | |
6 | |
7 #include "base/prefs/pref_service.h" | |
8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | |
9 #include "chrome/browser/geolocation/geolocation_infobar_delegate.h" | |
10 #include "chrome/browser/infobars/infobar_service.h" | |
11 #include "chrome/browser/media/midi_permission_infobar_delegate.h" | |
12 #include "chrome/browser/notifications/notification_permission_infobar_delegate. h" | |
13 #include "chrome/browser/permissions/permission_manager.h" | |
14 #include "chrome/browser/permissions/permission_manager_factory.h" | |
15 #include "chrome/browser/profiles/profile.h" | |
16 #include "chrome/browser/storage/durable_storage_permission_infobar_delegate.h" | |
17 #include "chrome/common/pref_names.h" | |
18 #include "components/content_settings/core/browser/host_content_settings_map.h" | |
19 #include "components/infobars/core/infobar.h" | |
20 #include "content/public/browser/browser_thread.h" | |
21 #include "content/public/browser/permission_type.h" | |
22 #include "content/public/browser/web_contents.h" | |
23 #include "content/public/common/permission_status.mojom.h" | |
24 | |
25 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
26 #include "chrome/browser/media/protected_media_identifier_infobar_delegate.h" | |
27 #endif | |
28 | |
29 using content::PermissionStatus; | |
30 using content::PermissionType; | |
31 | |
32 namespace { | |
33 | |
34 PermissionType ContentSettingsTypeToPermissionType(ContentSettingsType type) { | |
35 switch (type) { | |
36 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: | |
37 return PermissionType::MIDI_SYSEX; | |
38 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: | |
39 return PermissionType::NOTIFICATIONS; | |
40 case CONTENT_SETTINGS_TYPE_GEOLOCATION: | |
41 return PermissionType::GEOLOCATION; | |
42 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
43 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: | |
44 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; | |
45 #endif | |
46 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE: | |
47 return PermissionType::DURABLE_STORAGE; | |
48 default: | |
49 NOTREACHED(); | |
50 break; | |
51 } | |
52 return PermissionType::GEOLOCATION; | |
53 } | |
54 | |
55 ContentSetting PermissionStatusToContentSetting(PermissionStatus status) { | |
56 switch (status) { | |
57 case content::PERMISSION_STATUS_GRANTED: | |
58 return CONTENT_SETTING_ALLOW; | |
59 case content::PERMISSION_STATUS_DENIED: | |
60 return CONTENT_SETTING_BLOCK; | |
61 case content::PERMISSION_STATUS_ASK: | |
62 return CONTENT_SETTING_ASK; | |
63 default: | |
64 NOTREACHED(); | |
65 break; | |
66 } | |
67 return CONTENT_SETTING_BLOCK; | |
68 } | |
69 | |
70 } // anonymous namespace | |
71 | |
72 PermissionInfoBarRequest::PermissionRequest::PermissionRequest( | |
73 ContentSettingsType type, | |
74 const PermissionDecidedCallback& callback) | |
75 : type_(type), | |
76 callback_(callback) { | |
77 } | |
78 | |
79 PermissionInfoBarRequest::PermissionRequest::~PermissionRequest() { | |
80 } | |
81 | |
82 PermissionInfoBarRequest::PermissionInfoBarRequest( | |
83 int request_id, | |
84 const GURL& requesting_origin, | |
85 const GURL& embedding_origin, | |
86 const base::Closure& callback) | |
87 : infobar_(nullptr), | |
88 request_id_(request_id), | |
89 requesting_origin_(requesting_origin), | |
90 embedding_origin_(embedding_origin), | |
91 callback_(callback), | |
92 weak_factory_(this) { | |
93 } | |
94 | |
95 PermissionInfoBarRequest::~PermissionInfoBarRequest() { | |
96 } | |
97 | |
98 void PermissionInfoBarRequest::AddPermission( | |
99 const ContentSettingsType type, | |
100 const PermissionDecidedCallback& callback) { | |
101 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
102 DCHECK(!infobar_); | |
103 | |
104 requests_.push_back(PermissionRequest(type, callback)); | |
105 } | |
106 | |
107 bool PermissionInfoBarRequest::ShowInfobar( | |
108 content::WebContents* web_contents) { | |
109 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
110 DCHECK(!infobar_); | |
111 | |
112 Profile* profile = | |
113 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
114 DCHECK(profile); | |
115 | |
116 // After pruning if there is nothing left then just ignore this request. | |
117 PruneAnsweredPermissions(profile); | |
118 if (requests_.size() == 0) | |
119 return false; | |
120 | |
121 InfoBarService* infobar_service = | |
122 InfoBarService::FromWebContents(web_contents); | |
123 DCHECK(infobar_service); | |
124 | |
125 std::string display_languages = | |
126 profile->GetPrefs()->GetString(prefs::kAcceptLanguages); | |
127 if (requests_.size() == 1) { | |
128 CreateInfoBar( | |
129 infobar_service, | |
130 requests_[0], | |
131 display_languages, | |
132 base::Bind(&PermissionInfoBarRequest::OnPermissionSet, | |
133 weak_factory_.GetWeakPtr())); | |
134 return true; | |
135 } | |
136 | |
137 // TODO(lalitm) once multiple permissions is ready to land, this | |
138 // should be implemented properly. | |
139 NOTIMPLEMENTED(); | |
140 for (size_t i = 0; i < requests_.size(); ++i) | |
141 requests_[i].callback().Run(false, CONTENT_SETTING_DEFAULT); | |
142 return false; | |
143 } | |
144 | |
145 void PermissionInfoBarRequest::AcceptForTests() { | |
146 OnManualClose(); | |
147 OnPermissionsSet(true, | |
148 std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_ALLOW)); | |
149 } | |
150 | |
151 void PermissionInfoBarRequest::ClosingForTests() { | |
152 OnManualClose(); | |
153 OnPermissionsSet(false, | |
154 std::vector<ContentSetting>(requests_.size(), CONTENT_SETTING_DEFAULT)); | |
155 } | |
156 | |
157 void PermissionInfoBarRequest::Cancel() { | |
158 OnManualClose(); | |
159 callback_.Run(); | |
160 } | |
161 | |
162 void PermissionInfoBarRequest::OnManualClose() { | |
163 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
164 DCHECK(infobar_); | |
165 | |
166 infobar_->RemoveSelf(); | |
167 infobar_ = nullptr; | |
168 } | |
169 | |
170 void PermissionInfoBarRequest::OnPermissionSet( | |
171 bool update_content_setting, | |
172 bool allowed) { | |
173 OnPermissionsSet(update_content_setting, | |
174 std::vector<ContentSetting>(1, | |
175 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK)); | |
176 } | |
177 | |
178 void PermissionInfoBarRequest::OnPermissionsSet( | |
179 bool update_content_setting, | |
180 const std::vector<ContentSetting>& allowed) { | |
mlamouri (slow - plz ping)
2015/10/02 15:51:07
nit: allowed isn't a great named
Lalit Maganti
2015/10/02 16:06:43
Done.
| |
181 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
182 | |
183 // Set the infobar to nullptr so there is no attempt to remove it later. | |
184 infobar_ = nullptr; | |
185 | |
186 for (size_t i = 0; i < requests_.size(); ++i) { | |
187 requests_[i].callback() | |
188 .Run(update_content_setting, | |
189 update_content_setting ? allowed[i] : CONTENT_SETTING_DEFAULT); | |
mlamouri (slow - plz ping)
2015/10/02 15:51:07
Shouldn't that be a DCHECK()? that if !update_cont
Lalit Maganti
2015/10/02 16:06:43
Done.
| |
190 } | |
191 callback_.Run(); | |
192 } | |
193 | |
194 void PermissionInfoBarRequest::PruneAnsweredPermissions( | |
195 Profile* profile) { | |
196 for (auto it = requests_.begin(); it != requests_.end();) { | |
197 PermissionStatus status = PermissionManagerFactory::GetForProfile(profile) | |
198 ->GetPermissionStatus( | |
199 ContentSettingsTypeToPermissionType(it->type()), | |
200 requesting_origin_, | |
201 embedding_origin_); | |
202 if (status == content::PERMISSION_STATUS_GRANTED || | |
203 status == content::PERMISSION_STATUS_DENIED) { | |
204 it->callback().Run(true, | |
205 PermissionStatusToContentSetting(status)); | |
206 it = requests_.erase(it); | |
207 } else { | |
208 ++it; | |
209 } | |
210 } | |
211 } | |
212 | |
213 void PermissionInfoBarRequest::CreateInfoBar( | |
214 InfoBarService* infobar_service, | |
215 const PermissionRequest& request, | |
216 const std::string& display_languages, | |
217 const PermissionInfobarDelegate::PermissionSetCallback& callback) { | |
218 switch (request.type()) { | |
219 case CONTENT_SETTINGS_TYPE_GEOLOCATION: | |
220 infobar_ = GeolocationInfoBarDelegate::Create( | |
221 infobar_service, requesting_origin_, | |
222 display_languages, callback); | |
223 break; | |
224 #if defined(ENABLE_NOTIFICATIONS) | |
225 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: | |
226 infobar_ = NotificationPermissionInfobarDelegate::Create( | |
227 infobar_service, requesting_origin_, | |
228 display_languages, callback); | |
229 break; | |
230 #endif // ENABLE_NOTIFICATIONS | |
231 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: | |
232 infobar_ = MidiPermissionInfoBarDelegate::Create( | |
233 infobar_service, requesting_origin_, | |
234 display_languages, request.type(), callback); | |
235 break; | |
236 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
237 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: | |
238 infobar_ = ProtectedMediaIdentifierInfoBarDelegate::Create( | |
239 infobar_service, requesting_origin_, | |
240 display_languages, callback); | |
241 break; | |
242 #endif | |
243 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE: | |
244 infobar_ = DurableStoragePermissionInfoBarDelegate::Create( | |
245 infobar_service, requesting_origin_, | |
246 display_languages, request.type(), callback); | |
247 break; | |
248 default: | |
249 NOTREACHED(); | |
250 break; | |
251 } | |
252 } | |
OLD | NEW |