Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / private_api_misc.cc
blob6b89603cfebbf376b447e473bd6976aed762df83
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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/extensions/file_manager/private_api_misc.h"
7 #include <set>
8 #include <vector>
10 #include "ash/frame/frame_util.h"
11 #include "base/files/file_path.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chromeos/drive/file_system_util.h"
17 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
18 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
19 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
20 #include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
21 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
22 #include "chrome/browser/chromeos/file_system_provider/service.h"
23 #include "chrome/browser/chromeos/profiles/profile_helper.h"
24 #include "chrome/browser/chromeos/settings/cros_settings.h"
25 #include "chrome/browser/devtools/devtools_window.h"
26 #include "chrome/browser/extensions/api/file_handlers/mime_util.h"
27 #include "chrome/browser/extensions/devtools_util.h"
28 #include "chrome/browser/lifetime/application_lifetime.h"
29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/profiles/profiles_state.h"
32 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
33 #include "chrome/browser/signin/signin_manager_factory.h"
34 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
35 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
36 #include "chrome/common/extensions/api/file_manager_private.h"
37 #include "chrome/common/extensions/api/file_manager_private_internal.h"
38 #include "chrome/common/extensions/api/manifest_types.h"
39 #include "chrome/common/pref_names.h"
40 #include "chromeos/settings/timezone_settings.h"
41 #include "components/drive/drive_pref_names.h"
42 #include "components/drive/event_logger.h"
43 #include "components/signin/core/browser/profile_oauth2_token_service.h"
44 #include "components/signin/core/browser/signin_manager.h"
45 #include "components/user_manager/user_manager.h"
46 #include "content/public/browser/render_view_host.h"
47 #include "content/public/browser/web_contents.h"
48 #include "content/public/common/page_zoom.h"
49 #include "extensions/browser/app_window/app_window.h"
50 #include "extensions/browser/app_window/app_window_registry.h"
51 #include "google_apis/drive/auth_service.h"
52 #include "ui/base/webui/web_ui_util.h"
53 #include "url/gurl.h"
55 namespace extensions {
57 namespace {
58 const char kCWSScope[] = "https://www.googleapis.com/auth/chromewebstore";
60 // Obtains the current app window.
61 AppWindow* GetCurrentAppWindow(ChromeSyncExtensionFunction* function) {
62 content::WebContents* const contents = function->GetSenderWebContents();
63 return contents ?
64 AppWindowRegistry::Get(function->GetProfile())->
65 GetAppWindowForWebContents(contents) : nullptr;
68 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
69 GetLoggedInProfileInfoList() {
70 DCHECK(user_manager::UserManager::IsInitialized());
71 const std::vector<Profile*>& profiles =
72 g_browser_process->profile_manager()->GetLoadedProfiles();
73 std::set<Profile*> original_profiles;
74 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
75 result_profiles;
77 for (size_t i = 0; i < profiles.size(); ++i) {
78 // Filter the profile.
79 Profile* const profile = profiles[i]->GetOriginalProfile();
80 if (original_profiles.count(profile))
81 continue;
82 original_profiles.insert(profile);
83 const user_manager::User* const user =
84 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
85 if (!user || !user->is_logged_in())
86 continue;
88 // Make a ProfileInfo.
89 linked_ptr<api::file_manager_private::ProfileInfo> profile_info(
90 new api::file_manager_private::ProfileInfo());
91 profile_info->profile_id = multi_user_util::GetUserIDFromProfile(profile);
92 profile_info->display_name = UTF16ToUTF8(user->GetDisplayName());
93 // TODO(hirono): Remove the property from the profile_info.
94 profile_info->is_current_profile = true;
96 result_profiles.push_back(profile_info);
99 return result_profiles;
101 } // namespace
103 bool FileManagerPrivateLogoutUserForReauthenticationFunction::RunSync() {
104 const user_manager::User* user =
105 chromeos::ProfileHelper::Get()->GetUserByProfile(GetProfile());
106 if (user) {
107 user_manager::UserManager::Get()->SaveUserOAuthStatus(
108 user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
111 chrome::AttemptUserExit();
112 return true;
115 bool FileManagerPrivateGetPreferencesFunction::RunSync() {
116 api::file_manager_private::Preferences result;
117 const PrefService* const service = GetProfile()->GetPrefs();
119 result.drive_enabled = drive::util::IsDriveEnabledForProfile(GetProfile());
120 result.cellular_disabled =
121 service->GetBoolean(drive::prefs::kDisableDriveOverCellular);
122 result.hosted_files_disabled =
123 service->GetBoolean(drive::prefs::kDisableDriveHostedFiles);
124 result.search_suggest_enabled =
125 service->GetBoolean(prefs::kSearchSuggestEnabled);
126 result.use24hour_clock = service->GetBoolean(prefs::kUse24HourClock);
127 result.allow_redeem_offers = true;
128 if (!chromeos::CrosSettings::Get()->GetBoolean(
129 chromeos::kAllowRedeemChromeOsRegistrationOffers,
130 &result.allow_redeem_offers)) {
131 result.allow_redeem_offers = true;
133 result.timezone =
134 UTF16ToUTF8(chromeos::system::TimezoneSettings::GetInstance()
135 ->GetCurrentTimezoneID());
137 SetResult(result.ToValue().release());
139 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
140 if (logger)
141 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
142 return true;
145 bool FileManagerPrivateSetPreferencesFunction::RunSync() {
146 using extensions::api::file_manager_private::SetPreferences::Params;
147 const scoped_ptr<Params> params(Params::Create(*args_));
148 EXTENSION_FUNCTION_VALIDATE(params);
150 PrefService* const service = GetProfile()->GetPrefs();
152 if (params->change_info.cellular_disabled)
153 service->SetBoolean(drive::prefs::kDisableDriveOverCellular,
154 *params->change_info.cellular_disabled);
156 if (params->change_info.hosted_files_disabled)
157 service->SetBoolean(drive::prefs::kDisableDriveHostedFiles,
158 *params->change_info.hosted_files_disabled);
160 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
161 if (logger)
162 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
163 return true;
166 FileManagerPrivateInternalZipSelectionFunction::
167 FileManagerPrivateInternalZipSelectionFunction() {}
169 FileManagerPrivateInternalZipSelectionFunction::
170 ~FileManagerPrivateInternalZipSelectionFunction() {}
172 bool FileManagerPrivateInternalZipSelectionFunction::RunAsync() {
173 using extensions::api::file_manager_private_internal::ZipSelection::Params;
174 const scoped_ptr<Params> params(Params::Create(*args_));
175 EXTENSION_FUNCTION_VALIDATE(params);
177 // First param is the parent directory URL.
178 if (params->parent_url.empty())
179 return false;
181 base::FilePath src_dir = file_manager::util::GetLocalPathFromURL(
182 render_frame_host(), GetProfile(), GURL(params->parent_url));
183 if (src_dir.empty())
184 return false;
186 // Second param is the list of selected file URLs to be zipped.
187 if (params->urls.empty())
188 return false;
190 std::vector<base::FilePath> files;
191 for (size_t i = 0; i < params->urls.size(); ++i) {
192 base::FilePath path = file_manager::util::GetLocalPathFromURL(
193 render_frame_host(), GetProfile(), GURL(params->urls[i]));
194 if (path.empty())
195 return false;
196 files.push_back(path);
199 // Third param is the name of the output zip file.
200 if (params->dest_name.empty())
201 return false;
203 // Check if the dir path is under Drive mount point.
204 // TODO(hshi): support create zip file on Drive (crbug.com/158690).
205 if (drive::util::IsUnderDriveMountPoint(src_dir))
206 return false;
208 base::FilePath dest_file = src_dir.Append(params->dest_name);
209 std::vector<base::FilePath> src_relative_paths;
210 for (size_t i = 0; i != files.size(); ++i) {
211 const base::FilePath& file_path = files[i];
213 // Obtain the relative path of |file_path| under |src_dir|.
214 base::FilePath relative_path;
215 if (!src_dir.AppendRelativePath(file_path, &relative_path))
216 return false;
217 src_relative_paths.push_back(relative_path);
220 (new file_manager::ZipFileCreator(
221 base::Bind(&FileManagerPrivateInternalZipSelectionFunction::OnZipDone,
222 this),
223 src_dir, src_relative_paths, dest_file))
224 ->Start();
225 return true;
228 void FileManagerPrivateInternalZipSelectionFunction::OnZipDone(bool success) {
229 SetResult(new base::FundamentalValue(success));
230 SendResponse(true);
233 bool FileManagerPrivateZoomFunction::RunSync() {
234 using extensions::api::file_manager_private::Zoom::Params;
235 const scoped_ptr<Params> params(Params::Create(*args_));
236 EXTENSION_FUNCTION_VALIDATE(params);
238 content::PageZoom zoom_type;
239 switch (params->operation) {
240 case api::file_manager_private::ZOOM_OPERATION_TYPE_IN:
241 zoom_type = content::PAGE_ZOOM_IN;
242 break;
243 case api::file_manager_private::ZOOM_OPERATION_TYPE_OUT:
244 zoom_type = content::PAGE_ZOOM_OUT;
245 break;
246 case api::file_manager_private::ZOOM_OPERATION_TYPE_RESET:
247 zoom_type = content::PAGE_ZOOM_RESET;
248 break;
249 default:
250 NOTREACHED();
251 return false;
253 render_view_host_do_not_use()->Zoom(zoom_type);
254 return true;
257 FileManagerPrivateRequestWebStoreAccessTokenFunction::
258 FileManagerPrivateRequestWebStoreAccessTokenFunction() {
261 FileManagerPrivateRequestWebStoreAccessTokenFunction::
262 ~FileManagerPrivateRequestWebStoreAccessTokenFunction() {
265 bool FileManagerPrivateRequestWebStoreAccessTokenFunction::RunAsync() {
266 std::vector<std::string> scopes;
267 scopes.push_back(kCWSScope);
269 ProfileOAuth2TokenService* oauth_service =
270 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
271 net::URLRequestContextGetter* url_request_context_getter =
272 g_browser_process->system_request_context();
274 if (!oauth_service) {
275 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
276 if (logger) {
277 logger->Log(logging::LOG_ERROR,
278 "CWS OAuth token fetch failed. OAuth2TokenService can't "
279 "be retrieved.");
281 SetResult(base::Value::CreateNullValue());
282 return false;
285 SigninManagerBase* signin_manager =
286 SigninManagerFactory::GetForProfile(GetProfile());
287 auth_service_.reset(new google_apis::AuthService(
288 oauth_service,
289 signin_manager->GetAuthenticatedAccountId(),
290 url_request_context_getter,
291 scopes));
292 auth_service_->StartAuthentication(base::Bind(
293 &FileManagerPrivateRequestWebStoreAccessTokenFunction::
294 OnAccessTokenFetched,
295 this));
297 return true;
300 void FileManagerPrivateRequestWebStoreAccessTokenFunction::OnAccessTokenFetched(
301 google_apis::DriveApiErrorCode code,
302 const std::string& access_token) {
303 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
305 if (code == google_apis::HTTP_SUCCESS) {
306 DCHECK(auth_service_->HasAccessToken());
307 DCHECK(access_token == auth_service_->access_token());
308 if (logger)
309 logger->Log(logging::LOG_INFO, "CWS OAuth token fetch succeeded.");
310 SetResult(new base::StringValue(access_token));
311 SendResponse(true);
312 } else {
313 if (logger) {
314 logger->Log(logging::LOG_ERROR,
315 "CWS OAuth token fetch failed. (DriveApiErrorCode: %s)",
316 google_apis::DriveApiErrorCodeToString(code).c_str());
318 SetResult(base::Value::CreateNullValue());
319 SendResponse(false);
323 bool FileManagerPrivateGetProfilesFunction::RunSync() {
324 const std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >&
325 profiles = GetLoggedInProfileInfoList();
327 // Obtains the display profile ID.
328 AppWindow* const app_window = GetCurrentAppWindow(this);
329 chrome::MultiUserWindowManager* const window_manager =
330 chrome::MultiUserWindowManager::GetInstance();
331 const std::string current_profile_id =
332 multi_user_util::GetUserIDFromProfile(GetProfile());
333 const std::string display_profile_id =
334 window_manager && app_window ? window_manager->GetUserPresentingWindow(
335 app_window->GetNativeWindow())
336 : "";
338 results_ = api::file_manager_private::GetProfiles::Results::Create(
339 profiles,
340 current_profile_id,
341 display_profile_id.empty() ? current_profile_id : display_profile_id);
342 return true;
345 bool FileManagerPrivateOpenInspectorFunction::RunSync() {
346 using extensions::api::file_manager_private::OpenInspector::Params;
347 const scoped_ptr<Params> params(Params::Create(*args_));
348 EXTENSION_FUNCTION_VALIDATE(params);
350 switch (params->type) {
351 case extensions::api::file_manager_private::INSPECTION_TYPE_NORMAL:
352 // Open inspector for foreground page.
353 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents());
354 break;
355 case extensions::api::file_manager_private::INSPECTION_TYPE_CONSOLE:
356 // Open inspector for foreground page and bring focus to the console.
357 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents(),
358 DevToolsToggleAction::ShowConsole());
359 break;
360 case extensions::api::file_manager_private::INSPECTION_TYPE_ELEMENT:
361 // Open inspector for foreground page in inspect element mode.
362 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents(),
363 DevToolsToggleAction::Inspect());
364 break;
365 case extensions::api::file_manager_private::INSPECTION_TYPE_BACKGROUND:
366 // Open inspector for background page.
367 extensions::devtools_util::InspectBackgroundPage(extension(),
368 GetProfile());
369 break;
370 default:
371 NOTREACHED();
372 SetError(
373 base::StringPrintf("Unexpected inspection type(%d) is specified.",
374 static_cast<int>(params->type)));
375 return false;
377 return true;
380 FileManagerPrivateInternalGetMimeTypeFunction::
381 FileManagerPrivateInternalGetMimeTypeFunction() {
384 FileManagerPrivateInternalGetMimeTypeFunction::
385 ~FileManagerPrivateInternalGetMimeTypeFunction() {
388 bool FileManagerPrivateInternalGetMimeTypeFunction::RunAsync() {
389 using extensions::api::file_manager_private_internal::GetMimeType::Params;
390 const scoped_ptr<Params> params(Params::Create(*args_));
391 EXTENSION_FUNCTION_VALIDATE(params);
393 // Convert file url to local path.
394 const scoped_refptr<storage::FileSystemContext> file_system_context =
395 file_manager::util::GetFileSystemContextForRenderFrameHost(
396 GetProfile(), render_frame_host());
398 storage::FileSystemURL file_system_url(
399 file_system_context->CrackURL(GURL(params->url)));
401 app_file_handler_util::GetMimeTypeForLocalPath(
402 GetProfile(), file_system_url.path(),
403 base::Bind(&FileManagerPrivateInternalGetMimeTypeFunction::OnGetMimeType,
404 this));
406 return true;
409 void FileManagerPrivateInternalGetMimeTypeFunction::OnGetMimeType(
410 const std::string& mimeType) {
411 SetResult(new base::StringValue(mimeType));
412 SendResponse(true);
415 ExtensionFunction::ResponseAction
416 FileManagerPrivateIsPiexLoaderEnabledFunction::Run() {
417 #if defined(OFFICIAL_BUILD)
418 return RespondNow(OneArgument(new base::FundamentalValue(true)));
419 #else
420 return RespondNow(OneArgument(new base::FundamentalValue(false)));
421 #endif
424 FileManagerPrivateGetProvidingExtensionsFunction::
425 FileManagerPrivateGetProvidingExtensionsFunction()
426 : chrome_details_(this) {
429 ExtensionFunction::ResponseAction
430 FileManagerPrivateGetProvidingExtensionsFunction::Run() {
431 using chromeos::file_system_provider::Service;
432 using chromeos::file_system_provider::ProvidingExtensionInfo;
433 const Service* const service = Service::Get(chrome_details_.GetProfile());
434 const std::vector<ProvidingExtensionInfo> info_list =
435 service->GetProvidingExtensionInfoList();
437 using api::file_manager_private::ProvidingExtension;
438 std::vector<linked_ptr<ProvidingExtension>> providing_extensions;
439 for (const auto& info : info_list) {
440 const linked_ptr<ProvidingExtension> providing_extension(
441 new ProvidingExtension);
442 providing_extension->extension_id = info.extension_id;
443 providing_extension->name = info.name;
444 providing_extension->configurable = info.capabilities.configurable();
445 providing_extension->watchable = info.capabilities.watchable();
446 providing_extension->multiple_mounts = info.capabilities.multiple_mounts();
447 switch (info.capabilities.source()) {
448 case SOURCE_FILE:
449 providing_extension->source =
450 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_FILE;
451 break;
452 case SOURCE_DEVICE:
453 providing_extension->source =
454 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_DEVICE;
455 break;
456 case SOURCE_NETWORK:
457 providing_extension->source =
458 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_NETWORK;
459 break;
461 providing_extensions.push_back(providing_extension);
464 return RespondNow(ArgumentList(
465 api::file_manager_private::GetProvidingExtensions::Results::Create(
466 providing_extensions).Pass()));
469 FileManagerPrivateAddProvidedFileSystemFunction::
470 FileManagerPrivateAddProvidedFileSystemFunction()
471 : chrome_details_(this) {
474 ExtensionFunction::ResponseAction
475 FileManagerPrivateAddProvidedFileSystemFunction::Run() {
476 using extensions::api::file_manager_private::AddProvidedFileSystem::Params;
477 const scoped_ptr<Params> params(Params::Create(*args_));
478 EXTENSION_FUNCTION_VALIDATE(params);
480 using chromeos::file_system_provider::Service;
481 using chromeos::file_system_provider::ProvidingExtensionInfo;
482 Service* const service = Service::Get(chrome_details_.GetProfile());
484 if (!service->RequestMount(params->extension_id))
485 return RespondNow(Error("Failed to request a new mount."));
487 return RespondNow(NoArguments());
490 FileManagerPrivateConfigureVolumeFunction::
491 FileManagerPrivateConfigureVolumeFunction()
492 : chrome_details_(this) {
495 ExtensionFunction::ResponseAction
496 FileManagerPrivateConfigureVolumeFunction::Run() {
497 using extensions::api::file_manager_private::ConfigureVolume::Params;
498 const scoped_ptr<Params> params(Params::Create(*args_));
499 EXTENSION_FUNCTION_VALIDATE(params);
501 using file_manager::VolumeManager;
502 using file_manager::Volume;
503 VolumeManager* const volume_manager =
504 VolumeManager::Get(chrome_details_.GetProfile());
505 base::WeakPtr<Volume> volume =
506 volume_manager->FindVolumeById(params->volume_id);
507 if (!volume.get())
508 return RespondNow(Error("Volume not found."));
509 if (!volume->configurable())
510 return RespondNow(Error("Volume not configurable."));
512 switch (volume->type()) {
513 case file_manager::VOLUME_TYPE_PROVIDED: {
514 using chromeos::file_system_provider::Service;
515 Service* const service = Service::Get(chrome_details_.GetProfile());
516 DCHECK(service);
518 using chromeos::file_system_provider::ProvidedFileSystemInterface;
519 ProvidedFileSystemInterface* const file_system =
520 service->GetProvidedFileSystem(volume->extension_id(),
521 volume->file_system_id());
522 if (file_system)
523 file_system->Configure(base::Bind(
524 &FileManagerPrivateConfigureVolumeFunction::OnCompleted, this));
525 break;
527 default:
528 NOTIMPLEMENTED();
531 return RespondLater();
534 void FileManagerPrivateConfigureVolumeFunction::OnCompleted(
535 base::File::Error result) {
536 if (result != base::File::FILE_OK) {
537 Respond(Error("Failed to complete configuration."));
538 return;
541 Respond(NoArguments());
544 FileManagerPrivateInternalGetEntryActionsFunction::
545 FileManagerPrivateInternalGetEntryActionsFunction()
546 : chrome_details_(this) {
549 ExtensionFunction::ResponseAction
550 FileManagerPrivateInternalGetEntryActionsFunction::Run() {
551 using extensions::api::file_manager_private_internal::GetEntryActions::Params;
552 const scoped_ptr<Params> params(Params::Create(*args_));
553 EXTENSION_FUNCTION_VALIDATE(params);
555 const scoped_refptr<storage::FileSystemContext> file_system_context =
556 file_manager::util::GetFileSystemContextForRenderFrameHost(
557 chrome_details_.GetProfile(), render_frame_host());
559 const storage::FileSystemURL file_system_url(
560 file_system_context->CrackURL(GURL(params->url)));
562 chromeos::file_system_provider::util::FileSystemURLParser parser(
563 file_system_url);
564 if (!parser.Parse())
565 return RespondNow(Error("Related provided file system not found."));
567 parser.file_system()->GetActions(
568 parser.file_path(),
569 base::Bind(
570 &FileManagerPrivateInternalGetEntryActionsFunction::OnCompleted,
571 this));
572 return RespondLater();
575 void FileManagerPrivateInternalGetEntryActionsFunction::OnCompleted(
576 const chromeos::file_system_provider::Actions& actions,
577 base::File::Error result) {
578 if (result != base::File::FILE_OK) {
579 Respond(Error("Failed to fetch actions."));
580 return;
583 using api::file_system_provider::Action;
584 std::vector<linked_ptr<Action>> items;
585 for (const auto& action : actions) {
586 const linked_ptr<Action> item(new Action);
587 item->id = action.id;
588 item->title.reset(new std::string(action.title));
589 items.push_back(item);
592 Respond(ArgumentList(
593 api::file_manager_private_internal::GetEntryActions::Results::Create(
594 items)));
597 FileManagerPrivateInternalExecuteEntryActionFunction::
598 FileManagerPrivateInternalExecuteEntryActionFunction()
599 : chrome_details_(this) {
602 ExtensionFunction::ResponseAction
603 FileManagerPrivateInternalExecuteEntryActionFunction::Run() {
604 using extensions::api::file_manager_private_internal::ExecuteEntryAction::
605 Params;
606 const scoped_ptr<Params> params(Params::Create(*args_));
607 EXTENSION_FUNCTION_VALIDATE(params);
609 const scoped_refptr<storage::FileSystemContext> file_system_context =
610 file_manager::util::GetFileSystemContextForRenderFrameHost(
611 chrome_details_.GetProfile(), render_frame_host());
613 const storage::FileSystemURL file_system_url(
614 file_system_context->CrackURL(GURL(params->url)));
616 chromeos::file_system_provider::util::FileSystemURLParser parser(
617 file_system_url);
618 if (!parser.Parse())
619 return RespondNow(Error("Related provided file system not found."));
621 parser.file_system()->ExecuteAction(
622 parser.file_path(), params->action_id,
623 base::Bind(
624 &FileManagerPrivateInternalExecuteEntryActionFunction::OnCompleted,
625 this));
626 return RespondLater();
629 void FileManagerPrivateInternalExecuteEntryActionFunction::OnCompleted(
630 base::File::Error result) {
631 if (result != base::File::FILE_OK) {
632 Respond(Error("Failed to execute the action."));
633 return;
636 Respond(NoArguments());
639 } // namespace extensions