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

Side by Side Diff: chrome/browser/geolocation/chrome_geolocation_permission_context.cc

Issue 11183018: Refactor ChromeGeolocationPermissionContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updates from comments Created 8 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/geolocation/chrome_geolocation_permission_context.h" 5 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
6 6
7 #include <functional> 7 #include <functional>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 12 matching lines...) Expand all
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/render_view_host.h" 24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
26 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 26 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
28 28
29 using WebKit::WebSecurityOrigin; 29 using WebKit::WebSecurityOrigin;
30 using content::BrowserThread; 30 using content::BrowserThread;
31 using content::WebContents; 31 using content::WebContents;
32 32
33
34 // GeolocationPermissionContext ----------------------------------------------- 33 // GeolocationPermissionContext -----------------------------------------------
35 34
36 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext( 35 ChromeGeolocationPermissionContext* ChromeGeolocationPermissionContext::Create(
37 Profile* profile) 36 Profile* profile) {
38 : profile_(profile), 37 return new ChromeGeolocationPermissionContext(profile);
39 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_(
40 new GeolocationInfoBarQueueController(
41 base::Bind(
42 &ChromeGeolocationPermissionContext::NotifyPermissionSet,
43 base::Unretained(this)),
44 profile))) {
45 } 38 }
46 39
47 void ChromeGeolocationPermissionContext::RegisterUserPrefs( 40 void ChromeGeolocationPermissionContext::RegisterUserPrefs(
48 PrefService *user_prefs) { 41 PrefService *user_prefs) {
49 #if defined(OS_ANDROID) 42 #if defined(OS_ANDROID)
50 user_prefs->RegisterBooleanPref(prefs::kGeolocationEnabled, true, 43 user_prefs->RegisterBooleanPref(prefs::kGeolocationEnabled, true,
51 PrefService::UNSYNCABLE_PREF); 44 PrefService::UNSYNCABLE_PREF);
52 #endif 45 #endif
53 } 46 }
54 47
48 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext(
49 Profile* profile)
50 : profile_(profile) {
51 }
52
55 ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() { 53 ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() {
56 } 54 }
57 55
58 void ChromeGeolocationPermissionContext::RequestGeolocationPermission( 56 void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
59 int render_process_id, int render_view_id, int bridge_id, 57 int render_process_id, int render_view_id, int bridge_id,
60 const GURL& requesting_frame, base::Callback<void(bool)> callback) { 58 const GURL& requesting_frame, base::Callback<void(bool)> callback) {
61 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 59 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
62 BrowserThread::PostTask( 60 BrowserThread::PostTask(
63 BrowserThread::UI, FROM_HERE, 61 BrowserThread::UI, FROM_HERE,
64 base::Bind( 62 base::Bind(
65 &ChromeGeolocationPermissionContext::RequestGeolocationPermission, 63 &ChromeGeolocationPermissionContext::RequestGeolocationPermission,
66 this, render_process_id, render_view_id, bridge_id, 64 this, render_process_id, render_view_id, bridge_id,
67 requesting_frame, callback)); 65 requesting_frame, callback));
68 return; 66 return;
69 } 67 }
68
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70 WebContents* web_contents =
71 tab_util::GetWebContentsByID(render_process_id, render_view_id);
72 if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) {
73 // The tab may have gone away, or the request may not be from a tab at all.
74 // TODO(mpcomplete): the request could be from a background page or
75 // extension popup (tab_contents will have a different ViewType). But why do
76 // we care? Shouldn't we still put an infobar up in the current tab?
77 LOG(WARNING) << "Attempt to use geolocation tabless renderer: "
78 << render_process_id << "," << render_view_id << ","
79 << bridge_id << " (can't prompt user without a visible tab)";
80 NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
81 requesting_frame, callback, false);
82 return;
83 }
84
85 GURL embedder = web_contents->GetURL();
86 if (!requesting_frame.is_valid() || !embedder.is_valid()) {
87 LOG(WARNING) << "Attempt to use geolocation from an invalid URL: "
88 << requesting_frame << "," << embedder
89 << " (geolocation is not supported in popups)";
90 NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
91 requesting_frame, callback, false);
92 return;
93 }
94
95 DecidePermission(render_process_id, render_view_id, bridge_id,
96 requesting_frame, embedder, callback);
97 }
98
99 void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest(
100 int render_process_id,
101 int render_view_id,
102 int bridge_id,
103 const GURL& requesting_frame) {
104 CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id);
105 }
106
107 void ChromeGeolocationPermissionContext::DecidePermission(
108 int render_process_id, int render_view_id, int bridge_id,
109 const GURL& requesting_frame, const GURL& embedder,
110 base::Callback<void(bool)> callback) {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
71 112
72 #if defined(OS_ANDROID) 113 #if defined(OS_ANDROID)
73 // Check to see if the feature in its entirety has been disabled. 114 // Check to see if the feature in its entirety has been disabled.
74 // This must happen before other services (e.g. tabs, extensions) 115 // This must happen before other services (e.g. tabs, extensions)
75 // get an opportunity to allow the geolocation request. 116 // get an opportunity to allow the geolocation request.
76 if (!profile_->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) { 117 if (!profile()->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) {
77 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 118 PermissionDecided(render_process_id, render_view_id, bridge_id,
78 requesting_frame, callback, false); 119 requesting_frame, embedder, callback, false);
79 return; 120 return;
80 } 121 }
81 #endif 122 #endif
82 123
83 ExtensionService* extension_service = profile_->GetExtensionService(); 124 ExtensionService* extension_service = profile_->GetExtensionService();
84 if (extension_service) { 125 if (extension_service) {
85 const extensions::Extension* extension = 126 const extensions::Extension* extension =
86 extension_service->extensions()->GetExtensionOrAppByURL( 127 extension_service->extensions()->GetExtensionOrAppByURL(
87 ExtensionURLInfo( 128 ExtensionURLInfo(
88 WebSecurityOrigin::createFromString( 129 WebSecurityOrigin::createFromString(
89 UTF8ToUTF16(requesting_frame.spec())), 130 UTF8ToUTF16(requesting_frame.spec())),
90 requesting_frame)); 131 requesting_frame));
91 if (extension && 132 if (extension &&
92 extension->HasAPIPermission(extensions::APIPermission::kGeolocation)) { 133 extension->HasAPIPermission(extensions::APIPermission::kGeolocation)) {
93 // Make sure the extension is in the calling process. 134 // Make sure the extension is in the calling process.
94 if (extension_service->process_map()->Contains( 135 if (extension_service->process_map()->Contains(
95 extension->id(), render_process_id)) { 136 extension->id(), render_process_id)) {
96 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 137 PermissionDecided(render_process_id, render_view_id, bridge_id,
97 requesting_frame, callback, true); 138 requesting_frame, embedder, callback, true);
98 return; 139 return;
99 } 140 }
100 } 141 }
101 } 142 }
102 143
103 WebContents* web_contents =
104 tab_util::GetWebContentsByID(render_process_id, render_view_id);
105 if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) {
106 // The tab may have gone away, or the request may not be from a tab at all.
107 // TODO(mpcomplete): the request could be from a background page or
108 // extension popup (tab_contents will have a different ViewType). But why do
109 // we care? Shouldn't we still put an infobar up in the current tab?
110 LOG(WARNING) << "Attempt to use geolocation tabless renderer: "
111 << render_process_id << "," << render_view_id << ","
112 << bridge_id << " (can't prompt user without a visible tab)";
113 NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
114 requesting_frame, callback, false);
115 return;
116 }
117
118 GURL embedder = web_contents->GetURL();
119 if (!requesting_frame.is_valid() || !embedder.is_valid()) {
120 LOG(WARNING) << "Attempt to use geolocation from an invalid URL: "
121 << requesting_frame << "," << embedder
122 << " (geolocation is not supported in popups)";
123 NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
124 requesting_frame, callback, false);
125 return;
126 }
127
128 ContentSetting content_setting = 144 ContentSetting content_setting =
129 profile_->GetHostContentSettingsMap()->GetContentSetting( 145 profile_->GetHostContentSettingsMap()->GetContentSetting(
130 requesting_frame, 146 requesting_frame,
131 embedder, 147 embedder,
132 CONTENT_SETTINGS_TYPE_GEOLOCATION, 148 CONTENT_SETTINGS_TYPE_GEOLOCATION,
133 std::string()); 149 std::string());
134 if (content_setting == CONTENT_SETTING_BLOCK) { 150 switch (content_setting) {
135 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 151 case CONTENT_SETTING_BLOCK:
136 requesting_frame, callback, false); 152 PermissionDecided(render_process_id, render_view_id, bridge_id,
137 } else if (content_setting == CONTENT_SETTING_ALLOW) { 153 requesting_frame, embedder, callback, false);
138 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, 154 break;
139 requesting_frame, callback, true); 155 case CONTENT_SETTING_ALLOW:
140 } else { // setting == ask. Prompt the user. 156 PermissionDecided(render_process_id, render_view_id, bridge_id,
141 geolocation_infobar_queue_controller_->CreateInfoBarRequest( 157 requesting_frame, embedder, callback, true);
142 render_process_id, render_view_id, bridge_id, requesting_frame, 158 break;
143 embedder, callback); 159 default:
160 // setting == ask. Prompt the user.
161 QueueController()->CreateInfoBarRequest(
162 render_process_id, render_view_id, bridge_id, requesting_frame,
163 embedder, base::Bind(
164 &ChromeGeolocationPermissionContext::NotifyPermissionSet,
165 base::Unretained(this),
166 render_process_id, render_view_id, bridge_id, requesting_frame,
167 callback));
144 } 168 }
145 } 169 }
146 170
147 void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest( 171 void ChromeGeolocationPermissionContext::PermissionDecided(
148 int render_process_id, 172 int render_process_id,
149 int render_view_id, 173 int render_view_id,
150 int bridge_id, 174 int bridge_id,
151 const GURL& requesting_frame) { 175 const GURL& requesting_frame,
152 CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); 176 const GURL& embedder,
153 } 177 base::Callback<void(bool)> callback,
154 178 bool allowed) {
155 void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest( 179 NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
156 int render_process_id, 180 requesting_frame, callback, allowed);
157 int render_view_id,
158 int bridge_id) {
159 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
160 BrowserThread::PostTask(
161 BrowserThread::UI, FROM_HERE,
162 base::Bind(
163 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
164 this, render_process_id, render_view_id, bridge_id));
165 return;
166 }
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 geolocation_infobar_queue_controller_->CancelInfoBarRequest(
169 render_process_id,
170 render_view_id,
171 bridge_id);
172 } 181 }
173 182
174 void ChromeGeolocationPermissionContext::NotifyPermissionSet( 183 void ChromeGeolocationPermissionContext::NotifyPermissionSet(
175 int render_process_id, 184 int render_process_id,
176 int render_view_id, 185 int render_view_id,
177 int bridge_id, 186 int bridge_id,
178 const GURL& requesting_frame, 187 const GURL& requesting_frame,
179 base::Callback<void(bool)> callback, 188 base::Callback<void(bool)> callback,
180 bool allowed) { 189 bool allowed) {
181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182 191
183 // WebContents may have gone away (or not exists for extension). 192 // WebContents may have gone away (or not exists for extension).
184 TabSpecificContentSettings* content_settings = 193 TabSpecificContentSettings* content_settings =
185 TabSpecificContentSettings::Get(render_process_id, render_view_id); 194 TabSpecificContentSettings::Get(render_process_id, render_view_id);
186 if (content_settings) { 195 if (content_settings) {
187 content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(), 196 content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(),
188 allowed); 197 allowed);
189 } 198 }
190 199
191 callback.Run(allowed); 200 callback.Run(allowed);
192 } 201 }
202
203 GeolocationInfoBarQueueController*
204 ChromeGeolocationPermissionContext::QueueController() {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206 if (!geolocation_infobar_queue_controller_)
207 geolocation_infobar_queue_controller_.reset(CreateQueueController());
208 return geolocation_infobar_queue_controller_.get();
209 }
210
211 GeolocationInfoBarQueueController*
212 ChromeGeolocationPermissionContext::CreateQueueController() {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
214 return new GeolocationInfoBarQueueController(profile());
215 }
216
217 void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest(
218 int render_process_id,
219 int render_view_id,
220 int bridge_id) {
221 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
222 BrowserThread::PostTask(
223 BrowserThread::UI, FROM_HERE,
224 base::Bind(
225 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
226 this, render_process_id, render_view_id, bridge_id));
227 return;
228 }
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 QueueController()->CancelInfoBarRequest(
231 render_process_id,
232 render_view_id,
233 bridge_id);
234 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698