Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "apps/browser/api/app_runtime/app_runtime_api.h" | 7 #include "apps/browser/api/app_runtime/app_runtime_api.h" |
| 8 #include "apps/browser/file_handler_util.h" | 8 #include "apps/browser/file_handler_util.h" |
| 9 #include "apps/common/api/app_runtime.h" | 9 #include "apps/common/api/app_runtime.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 } | 82 } |
| 83 | 83 |
| 84 // Helper method to launch the platform app |extension| with no data. This | 84 // Helper method to launch the platform app |extension| with no data. This |
| 85 // should be called in the fallback case, where it has been impossible to | 85 // should be called in the fallback case, where it has been impossible to |
| 86 // load or obtain file launch data. | 86 // load or obtain file launch data. |
| 87 void LaunchPlatformAppWithNoData(Profile* profile, const Extension* extension) { | 87 void LaunchPlatformAppWithNoData(Profile* profile, const Extension* extension) { |
| 88 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 88 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 89 AppEventRouter::DispatchOnLaunchedEvent(profile, extension); | 89 AppEventRouter::DispatchOnLaunchedEvent(profile, extension); |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Class to handle launching of platform apps to open a specific path. | 92 // Class to handle launching of platform apps to open specific paths. |
| 93 // An instance of this class is created for each launch. The lifetime of these | 93 // An instance of this class is created for each launch. The lifetime of these |
| 94 // instances is managed by reference counted pointers. As long as an instance | 94 // instances is managed by reference counted pointers. As long as an instance |
| 95 // has outstanding tasks on a message queue it will be retained; once all | 95 // has outstanding tasks on a message queue it will be retained; once all |
| 96 // outstanding tasks are completed it will be deleted. | 96 // outstanding tasks are completed it will be deleted. |
| 97 class PlatformAppPathLauncher | 97 class PlatformAppPathLauncher |
| 98 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> { | 98 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> { |
| 99 public: | 99 public: |
| 100 PlatformAppPathLauncher(Profile* profile, | 100 PlatformAppPathLauncher(Profile* profile, |
| 101 const Extension* extension, | 101 const Extension* extension, |
| 102 const std::vector<base::FilePath>& file_paths) | |
| 103 : profile_(profile), extension_(extension), file_paths_(file_paths) {} | |
| 104 | |
| 105 PlatformAppPathLauncher(Profile* profile, | |
| 106 const Extension* extension, | |
| 102 const base::FilePath& file_path) | 107 const base::FilePath& file_path) |
| 103 : profile_(profile), extension_(extension), file_path_(file_path) {} | 108 : profile_(profile), extension_(extension) { |
| 109 if (!file_path.empty()) | |
| 110 file_paths_.push_back(file_path); | |
| 111 } | |
| 104 | 112 |
| 105 void Launch() { | 113 void Launch() { |
| 106 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 114 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 107 if (file_path_.empty()) { | 115 if (file_paths_.empty()) { |
| 108 LaunchPlatformAppWithNoData(profile_, extension_); | 116 LaunchPlatformAppWithNoData(profile_, extension_); |
| 109 return; | 117 return; |
| 110 } | 118 } |
| 111 | 119 |
| 112 DCHECK(file_path_.IsAbsolute()); | 120 for (size_t i = 0; i < file_paths_.size(); ++i) { |
| 121 DCHECK(file_paths_[i].IsAbsolute()); | |
| 122 } | |
| 113 | 123 |
| 114 if (HasFileSystemWritePermission(extension_)) { | 124 if (HasFileSystemWritePermission(extension_)) { |
| 115 std::vector<base::FilePath> paths; | |
| 116 paths.push_back(file_path_); | |
| 117 CheckWritableFiles( | 125 CheckWritableFiles( |
| 118 paths, | 126 file_paths_, |
| 119 profile_, | 127 profile_, |
| 120 false, | 128 false, |
| 121 base::Bind(&PlatformAppPathLauncher::OnFileValid, this), | 129 base::Bind(&PlatformAppPathLauncher::OnFileValid, this), |
| 122 base::Bind(&PlatformAppPathLauncher::OnFileInvalid, this)); | 130 base::Bind(&PlatformAppPathLauncher::OnFileInvalid, this)); |
| 123 return; | 131 return; |
| 124 } | 132 } |
| 125 | 133 |
| 126 OnFileValid(); | 134 OnFileValid(); |
| 127 } | 135 } |
| 128 | 136 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 141 } | 149 } |
| 142 | 150 |
| 143 private: | 151 private: |
| 144 friend class base::RefCountedThreadSafe<PlatformAppPathLauncher>; | 152 friend class base::RefCountedThreadSafe<PlatformAppPathLauncher>; |
| 145 | 153 |
| 146 virtual ~PlatformAppPathLauncher() {} | 154 virtual ~PlatformAppPathLauncher() {} |
| 147 | 155 |
| 148 void MakePathAbsolute(const base::FilePath& current_directory) { | 156 void MakePathAbsolute(const base::FilePath& current_directory) { |
| 149 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 157 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 150 | 158 |
| 151 if (!DoMakePathAbsolute(current_directory, &file_path_)) { | 159 for (std::vector<base::FilePath>::iterator it = file_paths_.begin(); |
| 152 LOG(WARNING) << "Cannot make absolute path from " << file_path_.value(); | 160 it != file_paths_.end(); |
| 153 file_path_ = base::FilePath(); | 161 ++it) { |
| 162 if (!DoMakePathAbsolute(current_directory, &*it)) { | |
| 163 LOG(WARNING) << "Cannot make absolute path from " << it->value(); | |
| 164 BrowserThread::PostTask( | |
| 165 BrowserThread::UI, | |
| 166 FROM_HERE, | |
| 167 base::Bind(&PlatformAppPathLauncher::LaunchWithNoLaunchData, this)); | |
| 168 return; | |
| 169 } | |
| 154 } | 170 } |
| 155 | 171 |
| 156 BrowserThread::PostTask(BrowserThread::UI, | 172 BrowserThread::PostTask(BrowserThread::UI, |
| 157 FROM_HERE, | 173 FROM_HERE, |
| 158 base::Bind(&PlatformAppPathLauncher::Launch, this)); | 174 base::Bind(&PlatformAppPathLauncher::Launch, this)); |
| 159 } | 175 } |
| 160 | 176 |
| 161 void OnFileValid() { | 177 void OnFileValid() { |
| 162 #if defined(OS_CHROMEOS) | 178 mime_types_.resize(file_paths_.size()); |
| 163 if (file_manager::util::IsUnderNonNativeLocalPath(profile_, file_path_)) { | 179 StepToFillMimeTypes(); |
|
benwells
2014/05/30 00:59:35
Sorry to be so nitpicky. I'm finding this logic pr
hirono
2014/05/30 02:53:44
Currently the mixed case should not happen, but it
benwells
2014/05/30 06:33:57
Ah, OK. Hmm. Maybe with some comments / changed na
hirono
2014/06/02 03:33:25
Done.
| |
| 164 file_manager::util::GetNonNativeLocalPathMimeType( | |
| 165 profile_, | |
| 166 file_path_, | |
| 167 base::Bind(&PlatformAppPathLauncher::OnGotMimeType, this)); | |
| 168 return; | |
| 169 } | |
| 170 #endif | |
| 171 | |
| 172 BrowserThread::PostTask( | |
| 173 BrowserThread::FILE, | |
| 174 FROM_HERE, | |
| 175 base::Bind(&PlatformAppPathLauncher::GetMimeTypeAndLaunch, this)); | |
| 176 } | 180 } |
| 177 | 181 |
| 178 void OnFileInvalid(const base::FilePath& /* error_path */) { | 182 void OnFileInvalid(const base::FilePath& /* error_path */) { |
| 179 LaunchWithNoLaunchData(); | 183 LaunchWithNoLaunchData(); |
| 180 } | 184 } |
| 181 | 185 |
| 186 void StepToFillMimeTypes() { | |
|
benwells
2014/05/30 06:33:57
I think the name GetNextNonNativeMimeType would be
hirono
2014/06/02 03:33:25
Done.
| |
| 187 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 188 | |
| 189 bool filled = true; | |
|
benwells
2014/05/30 06:33:57
Changing filled to any_native_files would be clear
hirono
2014/06/02 03:33:25
Done.
| |
| 190 | |
| 191 for (size_t i = 0; i < mime_types_.size(); ++i) { | |
| 192 if (!mime_types_[i].empty()) | |
| 193 continue; | |
| 194 const base::FilePath& file_path = file_paths_[i]; | |
| 195 #if defined(OS_CHROMEOS) | |
| 196 if (file_manager::util::IsUnderNonNativeLocalPath(profile_, file_path)) { | |
| 197 file_manager::util::GetNonNativeLocalPathMimeType( | |
| 198 profile_, | |
| 199 file_path, | |
| 200 base::Bind(&PlatformAppPathLauncher::OnGotMimeType, this, i)); | |
| 201 return; | |
| 202 } | |
| 203 #endif | |
| 204 filled = false; | |
| 205 } | |
| 206 | |
| 207 if (!filled) { | |
| 208 BrowserThread::PostTask( | |
| 209 BrowserThread::FILE, | |
| 210 FROM_HERE, | |
| 211 base::Bind(&PlatformAppPathLauncher::GetMimeTypeAndLaunch, this)); | |
| 212 return; | |
| 213 } | |
| 214 | |
| 215 LaunchWithMimeType(); | |
| 216 } | |
| 217 | |
| 182 void GetMimeTypeAndLaunch() { | 218 void GetMimeTypeAndLaunch() { |
|
benwells
2014/05/30 00:59:35
Nit: GetMimeTypesAndLaunch
hirono
2014/06/02 03:33:25
Done.
| |
| 183 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 219 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 184 | 220 |
| 185 // If the file doesn't exist, or is a directory, launch with no launch data. | 221 for (size_t i = 0; i < mime_types_.size(); ++i) { |
| 186 if (!base::PathExists(file_path_) || | 222 if (!this->mime_types_[i].empty()) |
|
benwells
2014/05/30 00:59:35
I think this would be a programming error. Maybe D
hirono
2014/05/30 02:53:44
It can happen, if the given files are mixed (nativ
benwells
2014/05/30 06:33:57
OK, great, thanks for explaining.
| |
| 187 base::DirectoryExists(file_path_)) { | 223 continue; |
| 188 LOG(WARNING) << "No file exists with path " << file_path_.value(); | 224 const base::FilePath& file_path = file_paths_[i]; |
| 189 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | 225 |
| 190 &PlatformAppPathLauncher::LaunchWithNoLaunchData, this)); | 226 // If the file doesn't exist, or is a directory, launch with no launch |
| 191 return; | 227 // data. |
| 228 if (!base::PathExists(file_path) || base::DirectoryExists(file_path)) { | |
| 229 LOG(WARNING) << "No file exists with path " << file_path.value(); | |
| 230 BrowserThread::PostTask( | |
| 231 BrowserThread::UI, | |
| 232 FROM_HERE, | |
| 233 base::Bind(&PlatformAppPathLauncher::LaunchWithNoLaunchData, this)); | |
| 234 return; | |
| 235 } | |
| 236 | |
| 237 std::string mime_type; | |
| 238 if (!net::GetMimeTypeFromFile(file_path, &mime_type)) { | |
| 239 // If MIME type of the file can't be determined by its path, | |
| 240 // try to sniff it by its content. | |
| 241 std::vector<char> content(net::kMaxBytesToSniff); | |
| 242 int bytes_read = base::ReadFile(file_path, &content[0], content.size()); | |
| 243 if (bytes_read >= 0) { | |
| 244 net::SniffMimeType(&content[0], | |
| 245 bytes_read, | |
| 246 net::FilePathToFileURL(file_path), | |
| 247 std::string(), // type_hint (passes no hint) | |
| 248 &mime_type); | |
| 249 } | |
| 250 if (mime_type.empty()) | |
| 251 mime_type = kFallbackMimeType; | |
| 252 } | |
| 253 mime_types_[i] = mime_type; | |
| 192 } | 254 } |
| 193 | 255 |
| 194 std::string mime_type; | 256 BrowserThread::PostTask( |
| 195 if (!net::GetMimeTypeFromFile(file_path_, &mime_type)) { | 257 BrowserThread::UI, |
| 196 // If MIME type of the file can't be determined by its path, | 258 FROM_HERE, |
| 197 // try to sniff it by its content. | 259 base::Bind(&PlatformAppPathLauncher::LaunchWithMimeType, this)); |
| 198 std::vector<char> content(net::kMaxBytesToSniff); | |
| 199 int bytes_read = base::ReadFile(file_path_, &content[0], content.size()); | |
| 200 if (bytes_read >= 0) { | |
| 201 net::SniffMimeType(&content[0], | |
| 202 bytes_read, | |
| 203 net::FilePathToFileURL(file_path_), | |
| 204 std::string(), // type_hint (passes no hint) | |
| 205 &mime_type); | |
| 206 } | |
| 207 if (mime_type.empty()) | |
| 208 mime_type = kFallbackMimeType; | |
| 209 } | |
| 210 | |
| 211 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
| 212 &PlatformAppPathLauncher::LaunchWithMimeType, this, mime_type)); | |
| 213 } | 260 } |
| 214 | 261 |
| 215 #if defined(OS_CHROMEOS) | 262 #if defined(OS_CHROMEOS) |
| 216 void OnGotMimeType(bool success, const std::string& mime_type) { | 263 void OnGotMimeType(size_t index, bool success, const std::string& mime_type) { |
| 217 if (!success) { | 264 if (!success) { |
| 218 LaunchWithNoLaunchData(); | 265 LaunchWithNoLaunchData(); |
| 219 return; | 266 return; |
| 220 } | 267 } |
| 221 LaunchWithMimeType(mime_type.empty() ? kFallbackMimeType : mime_type); | 268 mime_types_[index] = mime_type.empty() ? kFallbackMimeType : mime_type; |
| 269 StepToFillMimeTypes(); | |
| 222 } | 270 } |
| 223 #endif | 271 #endif |
| 224 | 272 |
| 225 void LaunchWithNoLaunchData() { | 273 void LaunchWithNoLaunchData() { |
| 226 // This method is required as an entry point on the UI thread. | 274 // This method is required as an entry point on the UI thread. |
| 227 LaunchPlatformAppWithNoData(profile_, extension_); | 275 LaunchPlatformAppWithNoData(profile_, extension_); |
| 228 } | 276 } |
| 229 | 277 |
| 230 void LaunchWithMimeType(const std::string& mime_type) { | 278 void LaunchWithMimeType() { |
|
benwells
2014/05/30 00:59:35
Nit: LaunchWithMimeTypes
hirono
2014/06/02 03:33:25
Done.
| |
| 279 DCHECK(file_paths_.size() == mime_types_.size()); | |
| 280 | |
| 231 // Find file handler from the platform app for the file being opened. | 281 // Find file handler from the platform app for the file being opened. |
| 232 const extensions::FileHandlerInfo* handler = NULL; | 282 const extensions::FileHandlerInfo* handler = NULL; |
| 233 if (!handler_id_.empty()) | 283 if (!handler_id_.empty()) { |
| 234 handler = FileHandlerForId(*extension_, handler_id_); | 284 handler = FileHandlerForId(*extension_, handler_id_); |
| 235 else | 285 if (handler) { |
| 236 handler = FirstFileHandlerForFile(*extension_, mime_type, file_path_); | 286 for (size_t i = 0; i < file_paths_.size(); ++i) { |
| 237 if (handler && !FileHandlerCanHandleFile(*handler, mime_type, file_path_)) { | 287 if (!FileHandlerCanHandleFile( |
| 238 LOG(WARNING) << "Extension does not provide a valid file handler for " | 288 *handler, mime_types_[i], file_paths_[i])) { |
| 239 << file_path_.value(); | 289 LOG(WARNING) |
| 240 LaunchWithNoLaunchData(); | 290 << "Extension does not provide a valid file handler for " |
| 241 return; | 291 << file_paths_[i].value(); |
| 292 handler = NULL; | |
| 293 break; | |
| 294 } | |
| 295 } | |
| 296 } | |
| 297 } else { | |
| 298 std::set<std::pair<base::FilePath, std::string> > path_and_file_type_set; | |
| 299 for (size_t i = 0; i < file_paths_.size(); ++i) { | |
| 300 path_and_file_type_set.insert( | |
| 301 std::make_pair(file_paths_[i], mime_types_[i])); | |
| 302 } | |
| 303 const std::vector<const extensions::FileHandlerInfo*>& handlers = | |
| 304 extensions::app_file_handler_util::FindFileHandlersForFiles( | |
| 305 *extension_, path_and_file_type_set); | |
| 306 if (!handlers.empty()) | |
| 307 handler = handlers[0]; | |
| 242 } | 308 } |
| 243 | 309 |
| 244 // If this app doesn't have a file handler that supports the file, launch | 310 // If this app doesn't have a file handler that supports the file, launch |
| 245 // with no launch data. | 311 // with no launch data. |
| 246 if (!handler) { | 312 if (!handler) { |
| 247 LOG(WARNING) << "Extension does not provide a valid file handler for " | 313 LOG(WARNING) << "Extension does not provide a valid file handler."; |
| 248 << file_path_.value(); | |
| 249 LaunchWithNoLaunchData(); | 314 LaunchWithNoLaunchData(); |
| 250 return; | 315 return; |
| 251 } | 316 } |
| 252 | 317 |
| 253 if (handler_id_.empty()) | 318 if (handler_id_.empty()) |
| 254 handler_id_ = handler->id; | 319 handler_id_ = handler->id; |
| 255 | 320 |
| 256 // Access needs to be granted to the file for the process associated with | 321 // Access needs to be granted to the file for the process associated with |
| 257 // the extension. To do this the ExtensionHost is needed. This might not be | 322 // the extension. To do this the ExtensionHost is needed. This might not be |
| 258 // available, or it might be in the process of being unloaded, in which case | 323 // available, or it might be in the process of being unloaded, in which case |
| 259 // the lazy background task queue is used to load the extension and then | 324 // the lazy background task queue is used to load the extension and then |
| 260 // call back to us. | 325 // call back to us. |
| 261 extensions::LazyBackgroundTaskQueue* queue = | 326 extensions::LazyBackgroundTaskQueue* const queue = |
| 262 ExtensionSystem::Get(profile_)->lazy_background_task_queue(); | 327 ExtensionSystem::Get(profile_)->lazy_background_task_queue(); |
| 263 if (queue->ShouldEnqueueTask(profile_, extension_)) { | 328 if (queue->ShouldEnqueueTask(profile_, extension_)) { |
| 264 queue->AddPendingTask(profile_, extension_->id(), base::Bind( | 329 queue->AddPendingTask( |
| 265 &PlatformAppPathLauncher::GrantAccessToFileAndLaunch, | 330 profile_, |
| 266 this, mime_type)); | 331 extension_->id(), |
| 332 base::Bind(&PlatformAppPathLauncher::GrantAccessToFilesAndLaunch, | |
| 333 this)); | |
| 267 return; | 334 return; |
| 268 } | 335 } |
| 269 | 336 |
| 270 extensions::ProcessManager* process_manager = | 337 extensions::ProcessManager* const process_manager = |
| 271 ExtensionSystem::Get(profile_)->process_manager(); | 338 ExtensionSystem::Get(profile_)->process_manager(); |
| 272 ExtensionHost* host = | 339 ExtensionHost* const host = |
| 273 process_manager->GetBackgroundHostForExtension(extension_->id()); | 340 process_manager->GetBackgroundHostForExtension(extension_->id()); |
| 274 DCHECK(host); | 341 DCHECK(host); |
| 275 GrantAccessToFileAndLaunch(mime_type, host); | 342 GrantAccessToFilesAndLaunch(host); |
| 276 } | 343 } |
| 277 | 344 |
| 278 void GrantAccessToFileAndLaunch(const std::string& mime_type, | 345 void GrantAccessToFilesAndLaunch(ExtensionHost* host) { |
| 279 ExtensionHost* host) { | |
| 280 // If there was an error loading the app page, |host| will be NULL. | 346 // If there was an error loading the app page, |host| will be NULL. |
| 281 if (!host) { | 347 if (!host) { |
| 282 LOG(ERROR) << "Could not load app page for " << extension_->id(); | 348 LOG(ERROR) << "Could not load app page for " << extension_->id(); |
| 283 return; | 349 return; |
| 284 } | 350 } |
| 285 | 351 |
| 286 GrantedFileEntry file_entry = | 352 std::vector<GrantedFileEntry> file_entries; |
| 287 CreateFileEntry(profile_, | 353 for (size_t i = 0; i < file_paths_.size(); ++i) { |
| 288 extension_, | 354 file_entries.push_back( |
| 289 host->render_process_host()->GetID(), | 355 CreateFileEntry(profile_, |
| 290 file_path_, | 356 extension_, |
| 291 false); | 357 host->render_process_host()->GetID(), |
| 292 AppEventRouter::DispatchOnLaunchedEventWithFileEntry( | 358 file_paths_[i], |
| 293 profile_, extension_, handler_id_, mime_type, file_entry); | 359 false)); |
| 360 } | |
| 361 | |
| 362 AppEventRouter::DispatchOnLaunchedEventWithFileEntries( | |
| 363 profile_, extension_, handler_id_, mime_types_, file_entries); | |
| 294 } | 364 } |
| 295 | 365 |
| 296 // The profile the app should be run in. | 366 // The profile the app should be run in. |
| 297 Profile* profile_; | 367 Profile* profile_; |
| 298 // The extension providing the app. | 368 // The extension providing the app. |
| 299 // TODO(benwells): Hold onto the extension ID instead of a pointer as it | 369 // TODO(benwells): Hold onto the extension ID instead of a pointer as it |
| 300 // is possible the extension will be unloaded while we're doing our thing. | 370 // is possible the extension will be unloaded while we're doing our thing. |
| 301 // See http://crbug.com/372270 for details. | 371 // See http://crbug.com/372270 for details. |
| 302 const Extension* extension_; | 372 const Extension* extension_; |
| 303 // The path to be passed through to the app. | 373 // The path to be passed through to the app. |
| 304 base::FilePath file_path_; | 374 std::vector<base::FilePath> file_paths_; |
| 375 std::vector<std::string> mime_types_; | |
| 305 // The ID of the file handler used to launch the app. | 376 // The ID of the file handler used to launch the app. |
| 306 std::string handler_id_; | 377 std::string handler_id_; |
| 307 | 378 |
| 308 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); | 379 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); |
| 309 }; | 380 }; |
| 310 | 381 |
| 311 } // namespace | 382 } // namespace |
| 312 | 383 |
| 313 void LaunchPlatformAppWithCommandLine(Profile* profile, | 384 void LaunchPlatformAppWithCommandLine(Profile* profile, |
| 314 const Extension* extension, | 385 const Extension* extension, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 launcher->Launch(); | 433 launcher->Launch(); |
| 363 } | 434 } |
| 364 | 435 |
| 365 void LaunchPlatformApp(Profile* profile, const Extension* extension) { | 436 void LaunchPlatformApp(Profile* profile, const Extension* extension) { |
| 366 LaunchPlatformAppWithCommandLine(profile, | 437 LaunchPlatformAppWithCommandLine(profile, |
| 367 extension, | 438 extension, |
| 368 CommandLine(CommandLine::NO_PROGRAM), | 439 CommandLine(CommandLine::NO_PROGRAM), |
| 369 base::FilePath()); | 440 base::FilePath()); |
| 370 } | 441 } |
| 371 | 442 |
| 372 void LaunchPlatformAppWithFileHandler(Profile* profile, | 443 void LaunchPlatformAppWithFileHandler( |
| 373 const Extension* extension, | 444 Profile* profile, |
| 374 const std::string& handler_id, | 445 const Extension* extension, |
| 375 const base::FilePath& file_path) { | 446 const std::string& handler_id, |
| 447 const std::vector<base::FilePath>& file_paths) { | |
| 376 scoped_refptr<PlatformAppPathLauncher> launcher = | 448 scoped_refptr<PlatformAppPathLauncher> launcher = |
| 377 new PlatformAppPathLauncher(profile, extension, file_path); | 449 new PlatformAppPathLauncher(profile, extension, file_paths); |
| 378 launcher->LaunchWithHandler(handler_id); | 450 launcher->LaunchWithHandler(handler_id); |
| 379 } | 451 } |
| 380 | 452 |
| 381 void RestartPlatformApp(Profile* profile, const Extension* extension) { | 453 void RestartPlatformApp(Profile* profile, const Extension* extension) { |
| 382 EventRouter* event_router = EventRouter::Get(profile); | 454 EventRouter* event_router = EventRouter::Get(profile); |
| 383 bool listening_to_restart = event_router-> | 455 bool listening_to_restart = event_router-> |
| 384 ExtensionHasEventListener(extension->id(), | 456 ExtensionHasEventListener(extension->id(), |
| 385 app_runtime::OnRestarted::kEventName); | 457 app_runtime::OnRestarted::kEventName); |
| 386 | 458 |
| 387 if (listening_to_restart) { | 459 if (listening_to_restart) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 404 void LaunchPlatformAppWithUrl(Profile* profile, | 476 void LaunchPlatformAppWithUrl(Profile* profile, |
| 405 const Extension* extension, | 477 const Extension* extension, |
| 406 const std::string& handler_id, | 478 const std::string& handler_id, |
| 407 const GURL& url, | 479 const GURL& url, |
| 408 const GURL& referrer_url) { | 480 const GURL& referrer_url) { |
| 409 AppEventRouter::DispatchOnLaunchedEventWithUrl( | 481 AppEventRouter::DispatchOnLaunchedEventWithUrl( |
| 410 profile, extension, handler_id, url, referrer_url); | 482 profile, extension, handler_id, url, referrer_url); |
| 411 } | 483 } |
| 412 | 484 |
| 413 } // namespace apps | 485 } // namespace apps |
| OLD | NEW |