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

Side by Side Diff: apps/launcher.cc

Issue 736233002: Remove bare extension pointer from platform app launcher code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Feedback Created 6 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "apps/launcher.h" 5 #include "apps/launcher.h"
6 6
7 #include <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 17 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
18 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" 18 #include "chrome/browser/extensions/api/file_handlers/mime_util.h"
19 #include "chrome/browser/extensions/api/file_system/file_system_api.h" 19 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/render_process_host.h" 22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
25 #include "content/public/common/url_constants.h" 25 #include "content/public/common/url_constants.h"
26 #include "extensions/browser/api/app_runtime/app_runtime_api.h" 26 #include "extensions/browser/api/app_runtime/app_runtime_api.h"
27 #include "extensions/browser/event_router.h" 27 #include "extensions/browser/event_router.h"
28 #include "extensions/browser/extension_host.h" 28 #include "extensions/browser/extension_host.h"
29 #include "extensions/browser/extension_prefs.h" 29 #include "extensions/browser/extension_prefs.h"
30 #include "extensions/browser/extension_registry.h"
30 #include "extensions/browser/extension_system.h" 31 #include "extensions/browser/extension_system.h"
31 #include "extensions/browser/granted_file_entry.h" 32 #include "extensions/browser/granted_file_entry.h"
32 #include "extensions/browser/lazy_background_task_queue.h" 33 #include "extensions/browser/lazy_background_task_queue.h"
33 #include "extensions/browser/process_manager.h" 34 #include "extensions/browser/process_manager.h"
34 #include "extensions/common/api/app_runtime.h" 35 #include "extensions/common/api/app_runtime.h"
35 #include "extensions/common/extension.h" 36 #include "extensions/common/extension.h"
36 #include "extensions/common/manifest_handlers/kiosk_mode_info.h" 37 #include "extensions/common/manifest_handlers/kiosk_mode_info.h"
37 #include "net/base/filename_util.h" 38 #include "net/base/filename_util.h"
38 #include "net/base/net_util.h" 39 #include "net/base/net_util.h"
39 #include "url/gurl.h" 40 #include "url/gurl.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 // instances is managed by reference counted pointers. As long as an instance 91 // instances is managed by reference counted pointers. As long as an instance
91 // has outstanding tasks on a message queue it will be retained; once all 92 // has outstanding tasks on a message queue it will be retained; once all
92 // outstanding tasks are completed it will be deleted. 93 // outstanding tasks are completed it will be deleted.
93 class PlatformAppPathLauncher 94 class PlatformAppPathLauncher
94 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> { 95 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> {
95 public: 96 public:
96 PlatformAppPathLauncher(Profile* profile, 97 PlatformAppPathLauncher(Profile* profile,
97 const Extension* extension, 98 const Extension* extension,
98 const std::vector<base::FilePath>& file_paths) 99 const std::vector<base::FilePath>& file_paths)
99 : profile_(profile), 100 : profile_(profile),
100 extension_(extension), 101 extension_id(extension->id()),
101 file_paths_(file_paths), 102 file_paths_(file_paths),
102 collector_(profile) {} 103 collector_(profile) {}
103 104
104 PlatformAppPathLauncher(Profile* profile, 105 PlatformAppPathLauncher(Profile* profile,
105 const Extension* extension, 106 const Extension* extension,
106 const base::FilePath& file_path) 107 const base::FilePath& file_path)
107 : profile_(profile), extension_(extension), collector_(profile) { 108 : profile_(profile), extension_id(extension->id()), collector_(profile) {
108 if (!file_path.empty()) 109 if (!file_path.empty())
109 file_paths_.push_back(file_path); 110 file_paths_.push_back(file_path);
110 } 111 }
111 112
112 void Launch() { 113 void Launch() {
113 DCHECK_CURRENTLY_ON(BrowserThread::UI); 114 DCHECK_CURRENTLY_ON(BrowserThread::UI);
115
116 const Extension* extension = GetExtension();
117 if (!extension)
118 return;
119
114 if (file_paths_.empty()) { 120 if (file_paths_.empty()) {
115 LaunchWithNoLaunchData(); 121 LaunchWithNoLaunchData();
116 return; 122 return;
117 } 123 }
118 124
119 for (size_t i = 0; i < file_paths_.size(); ++i) { 125 for (size_t i = 0; i < file_paths_.size(); ++i) {
120 DCHECK(file_paths_[i].IsAbsolute()); 126 DCHECK(file_paths_[i].IsAbsolute());
121 } 127 }
122 128
123 if (HasFileSystemWritePermission(extension_)) { 129 if (HasFileSystemWritePermission(extension)) {
124 PrepareFilesForWritableApp( 130 PrepareFilesForWritableApp(
125 file_paths_, 131 file_paths_,
126 profile_, 132 profile_,
127 false, 133 false,
128 base::Bind(&PlatformAppPathLauncher::OnFilesValid, this), 134 base::Bind(&PlatformAppPathLauncher::OnFilesValid, this),
129 base::Bind(&PlatformAppPathLauncher::OnFilesInvalid, this)); 135 base::Bind(&PlatformAppPathLauncher::OnFilesInvalid, this));
130 return; 136 return;
131 } 137 }
132 138
133 OnFilesValid(); 139 OnFilesValid();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 base::Bind(&PlatformAppPathLauncher::OnMimeTypesCollected, this)); 185 base::Bind(&PlatformAppPathLauncher::OnMimeTypesCollected, this));
180 } 186 }
181 187
182 void OnFilesInvalid(const base::FilePath& /* error_path */) { 188 void OnFilesInvalid(const base::FilePath& /* error_path */) {
183 LaunchWithNoLaunchData(); 189 LaunchWithNoLaunchData();
184 } 190 }
185 191
186 void LaunchWithNoLaunchData() { 192 void LaunchWithNoLaunchData() {
187 // This method is required as an entry point on the UI thread. 193 // This method is required as an entry point on the UI thread.
188 DCHECK_CURRENTLY_ON(BrowserThread::UI); 194 DCHECK_CURRENTLY_ON(BrowserThread::UI);
195
196 const Extension* extension = GetExtension();
197 if (!extension)
198 return;
199
189 AppRuntimeEventRouter::DispatchOnLaunchedEvent( 200 AppRuntimeEventRouter::DispatchOnLaunchedEvent(
190 profile_, extension_, extensions::SOURCE_FILE_HANDLER); 201 profile_, extension, extensions::SOURCE_FILE_HANDLER);
191 } 202 }
192 203
193 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) { 204 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) {
194 DCHECK(file_paths_.size() == mime_types->size()); 205 DCHECK(file_paths_.size() == mime_types->size());
195 206
207 const Extension* extension = GetExtension();
208 if (!extension)
209 return;
210
196 // If fetching a mime type failed, then use a fallback one. 211 // If fetching a mime type failed, then use a fallback one.
197 for (size_t i = 0; i < mime_types->size(); ++i) { 212 for (size_t i = 0; i < mime_types->size(); ++i) {
198 const std::string mime_type = 213 const std::string mime_type =
199 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType; 214 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType;
200 mime_types_.push_back(mime_type); 215 mime_types_.push_back(mime_type);
201 } 216 }
202 217
203 // Find file handler from the platform app for the file being opened. 218 // Find file handler from the platform app for the file being opened.
204 const extensions::FileHandlerInfo* handler = NULL; 219 const extensions::FileHandlerInfo* handler = NULL;
205 if (!handler_id_.empty()) { 220 if (!handler_id_.empty()) {
206 handler = FileHandlerForId(*extension_, handler_id_); 221 handler = FileHandlerForId(*extension, handler_id_);
207 if (handler) { 222 if (handler) {
208 for (size_t i = 0; i < file_paths_.size(); ++i) { 223 for (size_t i = 0; i < file_paths_.size(); ++i) {
209 if (!FileHandlerCanHandleFile( 224 if (!FileHandlerCanHandleFile(
210 *handler, mime_types_[i], file_paths_[i])) { 225 *handler, mime_types_[i], file_paths_[i])) {
211 LOG(WARNING) 226 LOG(WARNING)
212 << "Extension does not provide a valid file handler for " 227 << "Extension does not provide a valid file handler for "
213 << file_paths_[i].value(); 228 << file_paths_[i].value();
214 handler = NULL; 229 handler = NULL;
215 break; 230 break;
216 } 231 }
217 } 232 }
218 } 233 }
219 } else { 234 } else {
220 std::set<std::pair<base::FilePath, std::string> > path_and_file_type_set; 235 std::set<std::pair<base::FilePath, std::string> > path_and_file_type_set;
221 for (size_t i = 0; i < file_paths_.size(); ++i) { 236 for (size_t i = 0; i < file_paths_.size(); ++i) {
222 path_and_file_type_set.insert( 237 path_and_file_type_set.insert(
223 std::make_pair(file_paths_[i], mime_types_[i])); 238 std::make_pair(file_paths_[i], mime_types_[i]));
224 } 239 }
225 const std::vector<const extensions::FileHandlerInfo*>& handlers = 240 const std::vector<const extensions::FileHandlerInfo*>& handlers =
226 extensions::app_file_handler_util::FindFileHandlersForFiles( 241 extensions::app_file_handler_util::FindFileHandlersForFiles(
227 *extension_, path_and_file_type_set); 242 *extension, path_and_file_type_set);
228 if (!handlers.empty()) 243 if (!handlers.empty())
229 handler = handlers[0]; 244 handler = handlers[0];
230 } 245 }
231 246
232 // If this app doesn't have a file handler that supports the file, launch 247 // If this app doesn't have a file handler that supports the file, launch
233 // with no launch data. 248 // with no launch data.
234 if (!handler) { 249 if (!handler) {
235 LOG(WARNING) << "Extension does not provide a valid file handler."; 250 LOG(WARNING) << "Extension does not provide a valid file handler.";
236 LaunchWithNoLaunchData(); 251 LaunchWithNoLaunchData();
237 return; 252 return;
238 } 253 }
239 254
240 if (handler_id_.empty()) 255 if (handler_id_.empty())
241 handler_id_ = handler->id; 256 handler_id_ = handler->id;
242 257
243 // Access needs to be granted to the file for the process associated with 258 // Access needs to be granted to the file for the process associated with
244 // the extension. To do this the ExtensionHost is needed. This might not be 259 // the extension. To do this the ExtensionHost is needed. This might not be
245 // available, or it might be in the process of being unloaded, in which case 260 // available, or it might be in the process of being unloaded, in which case
246 // the lazy background task queue is used to load the extension and then 261 // the lazy background task queue is used to load the extension and then
247 // call back to us. 262 // call back to us.
248 extensions::LazyBackgroundTaskQueue* const queue = 263 extensions::LazyBackgroundTaskQueue* const queue =
249 ExtensionSystem::Get(profile_)->lazy_background_task_queue(); 264 ExtensionSystem::Get(profile_)->lazy_background_task_queue();
250 if (queue->ShouldEnqueueTask(profile_, extension_)) { 265 if (queue->ShouldEnqueueTask(profile_, extension)) {
251 queue->AddPendingTask( 266 queue->AddPendingTask(
252 profile_, 267 profile_, extension_id,
253 extension_->id(),
254 base::Bind(&PlatformAppPathLauncher::GrantAccessToFilesAndLaunch, 268 base::Bind(&PlatformAppPathLauncher::GrantAccessToFilesAndLaunch,
255 this)); 269 this));
256 return; 270 return;
257 } 271 }
258 272
259 extensions::ProcessManager* const process_manager = 273 extensions::ProcessManager* const process_manager =
260 extensions::ProcessManager::Get(profile_); 274 extensions::ProcessManager::Get(profile_);
261 ExtensionHost* const host = 275 ExtensionHost* const host =
262 process_manager->GetBackgroundHostForExtension(extension_->id()); 276 process_manager->GetBackgroundHostForExtension(extension_id);
263 DCHECK(host); 277 DCHECK(host);
264 GrantAccessToFilesAndLaunch(host); 278 GrantAccessToFilesAndLaunch(host);
265 } 279 }
266 280
267 void GrantAccessToFilesAndLaunch(ExtensionHost* host) { 281 void GrantAccessToFilesAndLaunch(ExtensionHost* host) {
282 const Extension* extension = GetExtension();
283 if (!extension)
284 return;
285
268 // If there was an error loading the app page, |host| will be NULL. 286 // If there was an error loading the app page, |host| will be NULL.
269 if (!host) { 287 if (!host) {
270 LOG(ERROR) << "Could not load app page for " << extension_->id(); 288 LOG(ERROR) << "Could not load app page for " << extension_id;
271 return; 289 return;
272 } 290 }
273 291
274 std::vector<GrantedFileEntry> file_entries; 292 std::vector<GrantedFileEntry> file_entries;
275 for (size_t i = 0; i < file_paths_.size(); ++i) { 293 for (size_t i = 0; i < file_paths_.size(); ++i) {
276 file_entries.push_back( 294 file_entries.push_back(CreateFileEntry(
277 CreateFileEntry(profile_, 295 profile_, extension, host->render_process_host()->GetID(),
278 extension_, 296 file_paths_[i], false));
279 host->render_process_host()->GetID(),
280 file_paths_[i],
281 false));
282 } 297 }
283 298
284 AppRuntimeEventRouter::DispatchOnLaunchedEventWithFileEntries( 299 AppRuntimeEventRouter::DispatchOnLaunchedEventWithFileEntries(
285 profile_, extension_, handler_id_, mime_types_, file_entries); 300 profile_, extension, handler_id_, mime_types_, file_entries);
301 }
302
303 const Extension* GetExtension() const {
304 return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
305 extension_id, extensions::ExtensionRegistry::EVERYTHING);
286 } 306 }
287 307
288 // The profile the app should be run in. 308 // The profile the app should be run in.
289 Profile* profile_; 309 Profile* profile_;
290 // The extension providing the app. 310 // The id of the extension providing the app. A pointer to the extension is
291 // TODO(benwells): Hold onto the extension ID instead of a pointer as it 311 // not kept as the extension may be unloaded and deleted during the course of
292 // is possible the extension will be unloaded while we're doing our thing. 312 // the launch.
293 // See http://crbug.com/372270 for details. 313 const std::string extension_id;
294 const Extension* extension_;
295 // The path to be passed through to the app. 314 // The path to be passed through to the app.
296 std::vector<base::FilePath> file_paths_; 315 std::vector<base::FilePath> file_paths_;
297 std::vector<std::string> mime_types_; 316 std::vector<std::string> mime_types_;
298 // The ID of the file handler used to launch the app. 317 // The ID of the file handler used to launch the app.
299 std::string handler_id_; 318 std::string handler_id_;
300 extensions::app_file_handler_util::MimeTypeCollector collector_; 319 extensions::app_file_handler_util::MimeTypeCollector collector_;
301 320
302 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); 321 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher);
303 }; 322 };
304 323
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 void LaunchPlatformAppWithUrl(Profile* profile, 425 void LaunchPlatformAppWithUrl(Profile* profile,
407 const Extension* extension, 426 const Extension* extension,
408 const std::string& handler_id, 427 const std::string& handler_id,
409 const GURL& url, 428 const GURL& url,
410 const GURL& referrer_url) { 429 const GURL& referrer_url) {
411 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl( 430 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl(
412 profile, extension, handler_id, url, referrer_url); 431 profile, extension, handler_id, url, referrer_url);
413 } 432 }
414 433
415 } // namespace apps 434 } // namespace apps
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698