Update all remaining Files app's private APIs to work on entries.
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / private_api_misc.cc
blob0d56a55ab6e2daa11af869528695352446991c86
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/drive_pref_names.h"
17 #include "chrome/browser/chromeos/drive/file_system_util.h"
18 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
19 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
20 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
21 #include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
22 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
23 #include "chrome/browser/chromeos/file_system_provider/service.h"
24 #include "chrome/browser/chromeos/profiles/profile_helper.h"
25 #include "chrome/browser/chromeos/settings/cros_settings.h"
26 #include "chrome/browser/devtools/devtools_window.h"
27 #include "chrome/browser/extensions/api/file_handlers/mime_util.h"
28 #include "chrome/browser/extensions/devtools_util.h"
29 #include "chrome/browser/lifetime/application_lifetime.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/profiles/profile_manager.h"
32 #include "chrome/browser/profiles/profiles_state.h"
33 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
34 #include "chrome/browser/signin/signin_manager_factory.h"
35 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
36 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
37 #include "chrome/common/extensions/api/file_manager_private.h"
38 #include "chrome/common/extensions/api/file_manager_private_internal.h"
39 #include "chrome/common/extensions/api/manifest_types.h"
40 #include "chrome/common/pref_names.h"
41 #include "components/drive/event_logger.h"
42 #include "components/signin/core/browser/profile_oauth2_token_service.h"
43 #include "components/signin/core/browser/signin_manager.h"
44 #include "components/user_manager/user_manager.h"
45 #include "content/public/browser/render_view_host.h"
46 #include "content/public/browser/web_contents.h"
47 #include "content/public/common/page_zoom.h"
48 #include "extensions/browser/app_window/app_window.h"
49 #include "extensions/browser/app_window/app_window_registry.h"
50 #include "google_apis/drive/auth_service.h"
51 #include "ui/base/webui/web_ui_util.h"
52 #include "url/gurl.h"
54 namespace extensions {
56 namespace {
57 const char kCWSScope[] = "https://www.googleapis.com/auth/chromewebstore";
59 // Obtains the current app window.
60 AppWindow* GetCurrentAppWindow(ChromeSyncExtensionFunction* function) {
61 content::WebContents* const contents = function->GetSenderWebContents();
62 return contents ?
63 AppWindowRegistry::Get(function->GetProfile())->
64 GetAppWindowForWebContents(contents) : nullptr;
67 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
68 GetLoggedInProfileInfoList() {
69 DCHECK(user_manager::UserManager::IsInitialized());
70 const std::vector<Profile*>& profiles =
71 g_browser_process->profile_manager()->GetLoadedProfiles();
72 std::set<Profile*> original_profiles;
73 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
74 result_profiles;
76 for (size_t i = 0; i < profiles.size(); ++i) {
77 // Filter the profile.
78 Profile* const profile = profiles[i]->GetOriginalProfile();
79 if (original_profiles.count(profile))
80 continue;
81 original_profiles.insert(profile);
82 const user_manager::User* const user =
83 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
84 if (!user || !user->is_logged_in())
85 continue;
87 // Make a ProfileInfo.
88 linked_ptr<api::file_manager_private::ProfileInfo> profile_info(
89 new api::file_manager_private::ProfileInfo());
90 profile_info->profile_id = multi_user_util::GetUserIDFromProfile(profile);
91 profile_info->display_name = UTF16ToUTF8(user->GetDisplayName());
92 // TODO(hirono): Remove the property from the profile_info.
93 profile_info->is_current_profile = true;
95 result_profiles.push_back(profile_info);
98 return result_profiles;
100 } // namespace
102 bool FileManagerPrivateLogoutUserForReauthenticationFunction::RunSync() {
103 const user_manager::User* user =
104 chromeos::ProfileHelper::Get()->GetUserByProfile(GetProfile());
105 if (user) {
106 user_manager::UserManager::Get()->SaveUserOAuthStatus(
107 user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
110 chrome::AttemptUserExit();
111 return true;
114 bool FileManagerPrivateGetPreferencesFunction::RunSync() {
115 api::file_manager_private::Preferences result;
116 const PrefService* const service = GetProfile()->GetPrefs();
118 result.drive_enabled = drive::util::IsDriveEnabledForProfile(GetProfile());
119 result.cellular_disabled =
120 service->GetBoolean(drive::prefs::kDisableDriveOverCellular);
121 result.hosted_files_disabled =
122 service->GetBoolean(drive::prefs::kDisableDriveHostedFiles);
123 result.search_suggest_enabled =
124 service->GetBoolean(prefs::kSearchSuggestEnabled);
125 result.use24hour_clock = service->GetBoolean(prefs::kUse24HourClock);
126 result.allow_redeem_offers = true;
127 if (!chromeos::CrosSettings::Get()->GetBoolean(
128 chromeos::kAllowRedeemChromeOsRegistrationOffers,
129 &result.allow_redeem_offers)) {
130 result.allow_redeem_offers = true;
133 SetResult(result.ToValue().release());
135 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
136 if (logger)
137 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
138 return true;
141 bool FileManagerPrivateSetPreferencesFunction::RunSync() {
142 using extensions::api::file_manager_private::SetPreferences::Params;
143 const scoped_ptr<Params> params(Params::Create(*args_));
144 EXTENSION_FUNCTION_VALIDATE(params);
146 PrefService* const service = GetProfile()->GetPrefs();
148 if (params->change_info.cellular_disabled)
149 service->SetBoolean(drive::prefs::kDisableDriveOverCellular,
150 *params->change_info.cellular_disabled);
152 if (params->change_info.hosted_files_disabled)
153 service->SetBoolean(drive::prefs::kDisableDriveHostedFiles,
154 *params->change_info.hosted_files_disabled);
156 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
157 if (logger)
158 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
159 return true;
162 FileManagerPrivateInternalZipSelectionFunction::
163 FileManagerPrivateInternalZipSelectionFunction() {}
165 FileManagerPrivateInternalZipSelectionFunction::
166 ~FileManagerPrivateInternalZipSelectionFunction() {}
168 bool FileManagerPrivateInternalZipSelectionFunction::RunAsync() {
169 using extensions::api::file_manager_private_internal::ZipSelection::Params;
170 const scoped_ptr<Params> params(Params::Create(*args_));
171 EXTENSION_FUNCTION_VALIDATE(params);
173 // First param is the parent directory URL.
174 if (params->parent_url.empty())
175 return false;
177 base::FilePath src_dir = file_manager::util::GetLocalPathFromURL(
178 render_frame_host(), GetProfile(), GURL(params->parent_url));
179 if (src_dir.empty())
180 return false;
182 // Second param is the list of selected file URLs to be zipped.
183 if (params->urls.empty())
184 return false;
186 std::vector<base::FilePath> files;
187 for (size_t i = 0; i < params->urls.size(); ++i) {
188 base::FilePath path = file_manager::util::GetLocalPathFromURL(
189 render_frame_host(), GetProfile(), GURL(params->urls[i]));
190 if (path.empty())
191 return false;
192 files.push_back(path);
195 // Third param is the name of the output zip file.
196 if (params->dest_name.empty())
197 return false;
199 // Check if the dir path is under Drive mount point.
200 // TODO(hshi): support create zip file on Drive (crbug.com/158690).
201 if (drive::util::IsUnderDriveMountPoint(src_dir))
202 return false;
204 base::FilePath dest_file = src_dir.Append(params->dest_name);
205 std::vector<base::FilePath> src_relative_paths;
206 for (size_t i = 0; i != files.size(); ++i) {
207 const base::FilePath& file_path = files[i];
209 // Obtain the relative path of |file_path| under |src_dir|.
210 base::FilePath relative_path;
211 if (!src_dir.AppendRelativePath(file_path, &relative_path))
212 return false;
213 src_relative_paths.push_back(relative_path);
216 (new file_manager::ZipFileCreator(
217 base::Bind(&FileManagerPrivateInternalZipSelectionFunction::OnZipDone,
218 this),
219 src_dir, src_relative_paths, dest_file))
220 ->Start();
221 return true;
224 void FileManagerPrivateInternalZipSelectionFunction::OnZipDone(bool success) {
225 SetResult(new base::FundamentalValue(success));
226 SendResponse(true);
229 bool FileManagerPrivateZoomFunction::RunSync() {
230 using extensions::api::file_manager_private::Zoom::Params;
231 const scoped_ptr<Params> params(Params::Create(*args_));
232 EXTENSION_FUNCTION_VALIDATE(params);
234 content::PageZoom zoom_type;
235 switch (params->operation) {
236 case api::file_manager_private::ZOOM_OPERATION_TYPE_IN:
237 zoom_type = content::PAGE_ZOOM_IN;
238 break;
239 case api::file_manager_private::ZOOM_OPERATION_TYPE_OUT:
240 zoom_type = content::PAGE_ZOOM_OUT;
241 break;
242 case api::file_manager_private::ZOOM_OPERATION_TYPE_RESET:
243 zoom_type = content::PAGE_ZOOM_RESET;
244 break;
245 default:
246 NOTREACHED();
247 return false;
249 render_view_host_do_not_use()->Zoom(zoom_type);
250 return true;
253 FileManagerPrivateRequestWebStoreAccessTokenFunction::
254 FileManagerPrivateRequestWebStoreAccessTokenFunction() {
257 FileManagerPrivateRequestWebStoreAccessTokenFunction::
258 ~FileManagerPrivateRequestWebStoreAccessTokenFunction() {
261 bool FileManagerPrivateRequestWebStoreAccessTokenFunction::RunAsync() {
262 std::vector<std::string> scopes;
263 scopes.push_back(kCWSScope);
265 ProfileOAuth2TokenService* oauth_service =
266 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
267 net::URLRequestContextGetter* url_request_context_getter =
268 g_browser_process->system_request_context();
270 if (!oauth_service) {
271 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
272 if (logger) {
273 logger->Log(logging::LOG_ERROR,
274 "CWS OAuth token fetch failed. OAuth2TokenService can't "
275 "be retrieved.");
277 SetResult(base::Value::CreateNullValue());
278 return false;
281 SigninManagerBase* signin_manager =
282 SigninManagerFactory::GetForProfile(GetProfile());
283 auth_service_.reset(new google_apis::AuthService(
284 oauth_service,
285 signin_manager->GetAuthenticatedAccountId(),
286 url_request_context_getter,
287 scopes));
288 auth_service_->StartAuthentication(base::Bind(
289 &FileManagerPrivateRequestWebStoreAccessTokenFunction::
290 OnAccessTokenFetched,
291 this));
293 return true;
296 void FileManagerPrivateRequestWebStoreAccessTokenFunction::OnAccessTokenFetched(
297 google_apis::DriveApiErrorCode code,
298 const std::string& access_token) {
299 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
301 if (code == google_apis::HTTP_SUCCESS) {
302 DCHECK(auth_service_->HasAccessToken());
303 DCHECK(access_token == auth_service_->access_token());
304 if (logger)
305 logger->Log(logging::LOG_INFO, "CWS OAuth token fetch succeeded.");
306 SetResult(new base::StringValue(access_token));
307 SendResponse(true);
308 } else {
309 if (logger) {
310 logger->Log(logging::LOG_ERROR,
311 "CWS OAuth token fetch failed. (DriveApiErrorCode: %s)",
312 google_apis::DriveApiErrorCodeToString(code).c_str());
314 SetResult(base::Value::CreateNullValue());
315 SendResponse(false);
319 bool FileManagerPrivateGetProfilesFunction::RunSync() {
320 const std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >&
321 profiles = GetLoggedInProfileInfoList();
323 // Obtains the display profile ID.
324 AppWindow* const app_window = GetCurrentAppWindow(this);
325 chrome::MultiUserWindowManager* const window_manager =
326 chrome::MultiUserWindowManager::GetInstance();
327 const std::string current_profile_id =
328 multi_user_util::GetUserIDFromProfile(GetProfile());
329 const std::string display_profile_id =
330 window_manager && app_window ? window_manager->GetUserPresentingWindow(
331 app_window->GetNativeWindow())
332 : "";
334 results_ = api::file_manager_private::GetProfiles::Results::Create(
335 profiles,
336 current_profile_id,
337 display_profile_id.empty() ? current_profile_id : display_profile_id);
338 return true;
341 bool FileManagerPrivateOpenInspectorFunction::RunSync() {
342 using extensions::api::file_manager_private::OpenInspector::Params;
343 const scoped_ptr<Params> params(Params::Create(*args_));
344 EXTENSION_FUNCTION_VALIDATE(params);
346 switch (params->type) {
347 case extensions::api::file_manager_private::INSPECTION_TYPE_NORMAL:
348 // Open inspector for foreground page.
349 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents());
350 break;
351 case extensions::api::file_manager_private::INSPECTION_TYPE_CONSOLE:
352 // Open inspector for foreground page and bring focus to the console.
353 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents(),
354 DevToolsToggleAction::ShowConsole());
355 break;
356 case extensions::api::file_manager_private::INSPECTION_TYPE_ELEMENT:
357 // Open inspector for foreground page in inspect element mode.
358 DevToolsWindow::OpenDevToolsWindow(GetSenderWebContents(),
359 DevToolsToggleAction::Inspect());
360 break;
361 case extensions::api::file_manager_private::INSPECTION_TYPE_BACKGROUND:
362 // Open inspector for background page.
363 extensions::devtools_util::InspectBackgroundPage(extension(),
364 GetProfile());
365 break;
366 default:
367 NOTREACHED();
368 SetError(
369 base::StringPrintf("Unexpected inspection type(%d) is specified.",
370 static_cast<int>(params->type)));
371 return false;
373 return true;
376 FileManagerPrivateInternalGetMimeTypeFunction::
377 FileManagerPrivateInternalGetMimeTypeFunction() {
380 FileManagerPrivateInternalGetMimeTypeFunction::
381 ~FileManagerPrivateInternalGetMimeTypeFunction() {
384 bool FileManagerPrivateInternalGetMimeTypeFunction::RunAsync() {
385 using extensions::api::file_manager_private_internal::GetMimeType::Params;
386 const scoped_ptr<Params> params(Params::Create(*args_));
387 EXTENSION_FUNCTION_VALIDATE(params);
389 // Convert file url to local path.
390 const scoped_refptr<storage::FileSystemContext> file_system_context =
391 file_manager::util::GetFileSystemContextForRenderFrameHost(
392 GetProfile(), render_frame_host());
394 storage::FileSystemURL file_system_url(
395 file_system_context->CrackURL(GURL(params->url)));
397 app_file_handler_util::GetMimeTypeForLocalPath(
398 GetProfile(), file_system_url.path(),
399 base::Bind(&FileManagerPrivateInternalGetMimeTypeFunction::OnGetMimeType,
400 this));
402 return true;
405 void FileManagerPrivateInternalGetMimeTypeFunction::OnGetMimeType(
406 const std::string& mimeType) {
407 SetResult(new base::StringValue(mimeType));
408 SendResponse(true);
411 ExtensionFunction::ResponseAction
412 FileManagerPrivateIsPiexLoaderEnabledFunction::Run() {
413 #if defined(OFFICIAL_BUILD)
414 return RespondNow(OneArgument(new base::FundamentalValue(true)));
415 #else
416 return RespondNow(OneArgument(new base::FundamentalValue(false)));
417 #endif
420 FileManagerPrivateGetProvidingExtensionsFunction::
421 FileManagerPrivateGetProvidingExtensionsFunction()
422 : chrome_details_(this) {
425 ExtensionFunction::ResponseAction
426 FileManagerPrivateGetProvidingExtensionsFunction::Run() {
427 using chromeos::file_system_provider::Service;
428 using chromeos::file_system_provider::ProvidingExtensionInfo;
429 const Service* const service = Service::Get(chrome_details_.GetProfile());
430 const std::vector<ProvidingExtensionInfo> info_list =
431 service->GetProvidingExtensionInfoList();
433 using api::file_manager_private::ProvidingExtension;
434 std::vector<linked_ptr<ProvidingExtension>> providing_extensions;
435 for (const auto& info : info_list) {
436 const linked_ptr<ProvidingExtension> providing_extension(
437 new ProvidingExtension);
438 providing_extension->extension_id = info.extension_id;
439 providing_extension->name = info.name;
440 providing_extension->configurable = info.capabilities.configurable();
441 providing_extension->watchable = info.capabilities.watchable();
442 providing_extension->multiple_mounts = info.capabilities.multiple_mounts();
443 switch (info.capabilities.source()) {
444 case SOURCE_FILE:
445 providing_extension->source =
446 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_FILE;
447 break;
448 case SOURCE_DEVICE:
449 providing_extension->source =
450 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_DEVICE;
451 break;
452 case SOURCE_NETWORK:
453 providing_extension->source =
454 api::manifest_types::FILE_SYSTEM_PROVIDER_SOURCE_NETWORK;
455 break;
457 providing_extensions.push_back(providing_extension);
460 return RespondNow(ArgumentList(
461 api::file_manager_private::GetProvidingExtensions::Results::Create(
462 providing_extensions).Pass()));
465 FileManagerPrivateAddProvidedFileSystemFunction::
466 FileManagerPrivateAddProvidedFileSystemFunction()
467 : chrome_details_(this) {
470 ExtensionFunction::ResponseAction
471 FileManagerPrivateAddProvidedFileSystemFunction::Run() {
472 using extensions::api::file_manager_private::AddProvidedFileSystem::Params;
473 const scoped_ptr<Params> params(Params::Create(*args_));
474 EXTENSION_FUNCTION_VALIDATE(params);
476 using chromeos::file_system_provider::Service;
477 using chromeos::file_system_provider::ProvidingExtensionInfo;
478 Service* const service = Service::Get(chrome_details_.GetProfile());
480 if (!service->RequestMount(params->extension_id))
481 return RespondNow(Error("Failed to request a new mount."));
483 return RespondNow(NoArguments());
486 FileManagerPrivateConfigureVolumeFunction::
487 FileManagerPrivateConfigureVolumeFunction()
488 : chrome_details_(this) {
491 ExtensionFunction::ResponseAction
492 FileManagerPrivateConfigureVolumeFunction::Run() {
493 using extensions::api::file_manager_private::ConfigureVolume::Params;
494 const scoped_ptr<Params> params(Params::Create(*args_));
495 EXTENSION_FUNCTION_VALIDATE(params);
497 using file_manager::VolumeManager;
498 using file_manager::Volume;
499 VolumeManager* const volume_manager =
500 VolumeManager::Get(chrome_details_.GetProfile());
501 base::WeakPtr<Volume> volume =
502 volume_manager->FindVolumeById(params->volume_id);
503 if (!volume.get())
504 return RespondNow(Error("Volume not found."));
505 if (!volume->configurable())
506 return RespondNow(Error("Volume not configurable."));
508 switch (volume->type()) {
509 case file_manager::VOLUME_TYPE_PROVIDED: {
510 using chromeos::file_system_provider::Service;
511 Service* const service = Service::Get(chrome_details_.GetProfile());
512 DCHECK(service);
514 using chromeos::file_system_provider::ProvidedFileSystemInterface;
515 ProvidedFileSystemInterface* const file_system =
516 service->GetProvidedFileSystem(volume->extension_id(),
517 volume->file_system_id());
518 if (file_system)
519 file_system->Configure(base::Bind(
520 &FileManagerPrivateConfigureVolumeFunction::OnCompleted, this));
521 break;
523 default:
524 NOTIMPLEMENTED();
527 return RespondLater();
530 void FileManagerPrivateConfigureVolumeFunction::OnCompleted(
531 base::File::Error result) {
532 if (result != base::File::FILE_OK) {
533 Respond(Error("Failed to complete configuration."));
534 return;
537 Respond(NoArguments());
540 FileManagerPrivateInternalGetEntryActionsFunction::
541 FileManagerPrivateInternalGetEntryActionsFunction()
542 : chrome_details_(this) {
545 ExtensionFunction::ResponseAction
546 FileManagerPrivateInternalGetEntryActionsFunction::Run() {
547 using extensions::api::file_manager_private_internal::GetEntryActions::Params;
548 const scoped_ptr<Params> params(Params::Create(*args_));
549 EXTENSION_FUNCTION_VALIDATE(params);
551 const scoped_refptr<storage::FileSystemContext> file_system_context =
552 file_manager::util::GetFileSystemContextForRenderFrameHost(
553 chrome_details_.GetProfile(), render_frame_host());
555 const storage::FileSystemURL file_system_url(
556 file_system_context->CrackURL(GURL(params->url)));
558 chromeos::file_system_provider::util::FileSystemURLParser parser(
559 file_system_url);
560 if (!parser.Parse())
561 return RespondNow(Error("Related provided file system not found."));
563 parser.file_system()->GetActions(
564 parser.file_path(),
565 base::Bind(
566 &FileManagerPrivateInternalGetEntryActionsFunction::OnCompleted,
567 this));
568 return RespondLater();
571 void FileManagerPrivateInternalGetEntryActionsFunction::OnCompleted(
572 const chromeos::file_system_provider::Actions& actions,
573 base::File::Error result) {
574 if (result != base::File::FILE_OK) {
575 Respond(Error("Failed to fetch actions."));
576 return;
579 using api::file_system_provider::Action;
580 std::vector<linked_ptr<Action>> items;
581 for (const auto& action : actions) {
582 const linked_ptr<Action> item(new Action);
583 item->id = action.id;
584 item->title.reset(new std::string(action.title));
585 items.push_back(item);
588 Respond(ArgumentList(
589 api::file_manager_private_internal::GetEntryActions::Results::Create(
590 items)));
593 FileManagerPrivateInternalExecuteEntryActionFunction::
594 FileManagerPrivateInternalExecuteEntryActionFunction()
595 : chrome_details_(this) {
598 ExtensionFunction::ResponseAction
599 FileManagerPrivateInternalExecuteEntryActionFunction::Run() {
600 using extensions::api::file_manager_private_internal::ExecuteEntryAction::
601 Params;
602 const scoped_ptr<Params> params(Params::Create(*args_));
603 EXTENSION_FUNCTION_VALIDATE(params);
605 const scoped_refptr<storage::FileSystemContext> file_system_context =
606 file_manager::util::GetFileSystemContextForRenderFrameHost(
607 chrome_details_.GetProfile(), render_frame_host());
609 const storage::FileSystemURL file_system_url(
610 file_system_context->CrackURL(GURL(params->url)));
612 chromeos::file_system_provider::util::FileSystemURLParser parser(
613 file_system_url);
614 if (!parser.Parse())
615 return RespondNow(Error("Related provided file system not found."));
617 parser.file_system()->ExecuteAction(
618 parser.file_path(), params->action_id,
619 base::Bind(
620 &FileManagerPrivateInternalExecuteEntryActionFunction::OnCompleted,
621 this));
622 return RespondLater();
625 void FileManagerPrivateInternalExecuteEntryActionFunction::OnCompleted(
626 base::File::Error result) {
627 if (result != base::File::FILE_OK) {
628 Respond(Error("Failed to execute the action."));
629 return;
632 Respond(NoArguments());
635 } // namespace extensions