Wire FSP API's onConfigureRequested to chrome.fileManagerPrivate.
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / private_api_misc.cc
blobba1f7570f6f07b09fa0b0f524044da0dde6f7e58
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 "ash/frame/frame_util.h"
8 #include "base/files/file_path.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/drive/file_system_util.h"
14 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
15 #include "chrome/browser/chromeos/file_manager/app_installer.h"
16 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
17 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
18 #include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
19 #include "chrome/browser/chromeos/file_system_provider/service.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "chrome/browser/devtools/devtools_window.h"
23 #include "chrome/browser/drive/event_logger.h"
24 #include "chrome/browser/extensions/api/file_handlers/mime_util.h"
25 #include "chrome/browser/extensions/devtools_util.h"
26 #include "chrome/browser/lifetime/application_lifetime.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/profiles/profile_manager.h"
29 #include "chrome/browser/profiles/profiles_state.h"
30 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
31 #include "chrome/browser/signin/signin_manager_factory.h"
32 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
33 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
34 #include "chrome/common/extensions/api/file_manager_private.h"
35 #include "chrome/common/pref_names.h"
36 #include "components/signin/core/browser/profile_oauth2_token_service.h"
37 #include "components/signin/core/browser/signin_manager.h"
38 #include "components/user_manager/user_manager.h"
39 #include "content/public/browser/render_view_host.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/page_zoom.h"
42 #include "extensions/browser/app_window/app_window.h"
43 #include "extensions/browser/app_window/app_window_registry.h"
44 #include "google_apis/drive/auth_service.h"
45 #include "ui/base/webui/web_ui_util.h"
46 #include "url/gurl.h"
48 namespace extensions {
50 namespace {
51 const char kCWSScope[] = "https://www.googleapis.com/auth/chromewebstore";
52 const char kGoogleCastApiExtensionId[] = "mafeflapfdfljijmlienjedomfjfmhpd";
54 // Obtains the current app window.
55 AppWindow* GetCurrentAppWindow(ChromeSyncExtensionFunction* function) {
56 AppWindowRegistry* const app_window_registry =
57 AppWindowRegistry::Get(function->GetProfile());
58 content::WebContents* const contents = function->GetAssociatedWebContents();
59 content::RenderViewHost* const render_view_host =
60 contents ? contents->GetRenderViewHost() : NULL;
61 return render_view_host ? app_window_registry->GetAppWindowForRenderViewHost(
62 render_view_host)
63 : NULL;
66 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
67 GetLoggedInProfileInfoList() {
68 DCHECK(user_manager::UserManager::IsInitialized());
69 const std::vector<Profile*>& profiles =
70 g_browser_process->profile_manager()->GetLoadedProfiles();
71 std::set<Profile*> original_profiles;
72 std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >
73 result_profiles;
75 for (size_t i = 0; i < profiles.size(); ++i) {
76 // Filter the profile.
77 Profile* const profile = profiles[i]->GetOriginalProfile();
78 if (original_profiles.count(profile))
79 continue;
80 original_profiles.insert(profile);
81 const user_manager::User* const user =
82 chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
83 if (!user || !user->is_logged_in())
84 continue;
86 // Make a ProfileInfo.
87 linked_ptr<api::file_manager_private::ProfileInfo> profile_info(
88 new api::file_manager_private::ProfileInfo());
89 profile_info->profile_id = multi_user_util::GetUserIDFromProfile(profile);
90 profile_info->display_name = UTF16ToUTF8(user->GetDisplayName());
91 // TODO(hirono): Remove the property from the profile_info.
92 profile_info->is_current_profile = true;
94 result_profiles.push_back(profile_info);
97 return result_profiles;
99 } // namespace
101 bool FileManagerPrivateLogoutUserForReauthenticationFunction::RunSync() {
102 const user_manager::User* user =
103 chromeos::ProfileHelper::Get()->GetUserByProfile(GetProfile());
104 if (user) {
105 user_manager::UserManager::Get()->SaveUserOAuthStatus(
106 user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
109 chrome::AttemptUserExit();
110 return true;
113 bool FileManagerPrivateGetPreferencesFunction::RunSync() {
114 api::file_manager_private::Preferences result;
115 const PrefService* const service = GetProfile()->GetPrefs();
117 result.drive_enabled = drive::util::IsDriveEnabledForProfile(GetProfile());
118 result.cellular_disabled =
119 service->GetBoolean(prefs::kDisableDriveOverCellular);
120 result.hosted_files_disabled =
121 service->GetBoolean(prefs::kDisableDriveHostedFiles);
122 result.use24hour_clock = service->GetBoolean(prefs::kUse24HourClock);
123 result.allow_redeem_offers = true;
124 if (!chromeos::CrosSettings::Get()->GetBoolean(
125 chromeos::kAllowRedeemChromeOsRegistrationOffers,
126 &result.allow_redeem_offers)) {
127 result.allow_redeem_offers = true;
130 SetResult(result.ToValue().release());
132 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
133 if (logger)
134 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
135 return true;
138 bool FileManagerPrivateSetPreferencesFunction::RunSync() {
139 using extensions::api::file_manager_private::SetPreferences::Params;
140 const scoped_ptr<Params> params(Params::Create(*args_));
141 EXTENSION_FUNCTION_VALIDATE(params);
143 PrefService* const service = GetProfile()->GetPrefs();
145 if (params->change_info.cellular_disabled)
146 service->SetBoolean(prefs::kDisableDriveOverCellular,
147 *params->change_info.cellular_disabled);
149 if (params->change_info.hosted_files_disabled)
150 service->SetBoolean(prefs::kDisableDriveHostedFiles,
151 *params->change_info.hosted_files_disabled);
153 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
154 if (logger)
155 logger->Log(logging::LOG_INFO, "%s succeeded.", name());
156 return true;
159 FileManagerPrivateZipSelectionFunction::
160 FileManagerPrivateZipSelectionFunction() {}
162 FileManagerPrivateZipSelectionFunction::
163 ~FileManagerPrivateZipSelectionFunction() {}
165 bool FileManagerPrivateZipSelectionFunction::RunAsync() {
166 using extensions::api::file_manager_private::ZipSelection::Params;
167 const scoped_ptr<Params> params(Params::Create(*args_));
168 EXTENSION_FUNCTION_VALIDATE(params);
170 // First param is the source directory URL.
171 if (params->dir_url.empty())
172 return false;
174 base::FilePath src_dir = file_manager::util::GetLocalPathFromURL(
175 render_view_host(), GetProfile(), GURL(params->dir_url));
176 if (src_dir.empty())
177 return false;
179 // Second param is the list of selected file URLs.
180 if (params->selection_urls.empty())
181 return false;
183 std::vector<base::FilePath> files;
184 for (size_t i = 0; i < params->selection_urls.size(); ++i) {
185 base::FilePath path = file_manager::util::GetLocalPathFromURL(
186 render_view_host(), GetProfile(), GURL(params->selection_urls[i]));
187 if (path.empty())
188 return false;
189 files.push_back(path);
192 // Third param is the name of the output zip file.
193 if (params->dest_name.empty())
194 return false;
196 // Check if the dir path is under Drive mount point.
197 // TODO(hshi): support create zip file on Drive (crbug.com/158690).
198 if (drive::util::IsUnderDriveMountPoint(src_dir))
199 return false;
201 base::FilePath dest_file = src_dir.Append(params->dest_name);
202 std::vector<base::FilePath> src_relative_paths;
203 for (size_t i = 0; i != files.size(); ++i) {
204 const base::FilePath& file_path = files[i];
206 // Obtain the relative path of |file_path| under |src_dir|.
207 base::FilePath relative_path;
208 if (!src_dir.AppendRelativePath(file_path, &relative_path))
209 return false;
210 src_relative_paths.push_back(relative_path);
213 (new file_manager::ZipFileCreator(
214 base::Bind(&FileManagerPrivateZipSelectionFunction::OnZipDone, this),
215 src_dir,
216 src_relative_paths,
217 dest_file))->Start();
218 return true;
221 void FileManagerPrivateZipSelectionFunction::OnZipDone(bool success) {
222 SetResult(new base::FundamentalValue(success));
223 SendResponse(true);
226 bool FileManagerPrivateZoomFunction::RunSync() {
227 using extensions::api::file_manager_private::Zoom::Params;
228 const scoped_ptr<Params> params(Params::Create(*args_));
229 EXTENSION_FUNCTION_VALIDATE(params);
231 content::PageZoom zoom_type;
232 switch (params->operation) {
233 case api::file_manager_private::ZOOM_OPERATION_TYPE_IN:
234 zoom_type = content::PAGE_ZOOM_IN;
235 break;
236 case api::file_manager_private::ZOOM_OPERATION_TYPE_OUT:
237 zoom_type = content::PAGE_ZOOM_OUT;
238 break;
239 case api::file_manager_private::ZOOM_OPERATION_TYPE_RESET:
240 zoom_type = content::PAGE_ZOOM_RESET;
241 break;
242 default:
243 NOTREACHED();
244 return false;
246 render_view_host()->Zoom(zoom_type);
247 return true;
250 bool FileManagerPrivateInstallWebstoreItemFunction::RunAsync() {
251 using extensions::api::file_manager_private::InstallWebstoreItem::Params;
252 const scoped_ptr<Params> params(Params::Create(*args_));
253 EXTENSION_FUNCTION_VALIDATE(params);
255 if (params->item_id.empty())
256 return false;
258 const extensions::WebstoreStandaloneInstaller::Callback callback =
259 base::Bind(
260 &FileManagerPrivateInstallWebstoreItemFunction::OnInstallComplete,
261 this);
263 // Only GoogleCastAPI extension can use silent installation.
264 if (params->silent_installation &&
265 params->item_id != kGoogleCastApiExtensionId) {
266 SetError("Only whitelisted items can do silent installation.");
267 return false;
270 scoped_refptr<file_manager::AppInstaller> installer(
271 new file_manager::AppInstaller(GetAssociatedWebContents(),
272 params->item_id,
273 GetProfile(),
274 params->silent_installation,
275 callback));
276 // installer will be AddRef()'d in BeginInstall().
277 installer->BeginInstall();
278 return true;
281 void FileManagerPrivateInstallWebstoreItemFunction::OnInstallComplete(
282 bool success,
283 const std::string& error,
284 extensions::webstore_install::Result result) {
285 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
286 if (success) {
287 if (logger) {
288 logger->Log(logging::LOG_INFO,
289 "App install succeeded. (item id: %s)",
290 webstore_item_id_.c_str());
292 } else {
293 if (logger) {
294 logger->Log(logging::LOG_ERROR,
295 "App install failed. (item id: %s, reason: %s)",
296 webstore_item_id_.c_str(),
297 error.c_str());
299 SetError(error);
302 SendResponse(success);
305 FileManagerPrivateRequestWebStoreAccessTokenFunction::
306 FileManagerPrivateRequestWebStoreAccessTokenFunction() {
309 FileManagerPrivateRequestWebStoreAccessTokenFunction::
310 ~FileManagerPrivateRequestWebStoreAccessTokenFunction() {
313 bool FileManagerPrivateRequestWebStoreAccessTokenFunction::RunAsync() {
314 std::vector<std::string> scopes;
315 scopes.push_back(kCWSScope);
317 ProfileOAuth2TokenService* oauth_service =
318 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
319 net::URLRequestContextGetter* url_request_context_getter =
320 g_browser_process->system_request_context();
322 if (!oauth_service) {
323 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
324 if (logger) {
325 logger->Log(logging::LOG_ERROR,
326 "CWS OAuth token fetch failed. OAuth2TokenService can't "
327 "be retrieved.");
329 SetResult(base::Value::CreateNullValue());
330 return false;
333 SigninManagerBase* signin_manager =
334 SigninManagerFactory::GetForProfile(GetProfile());
335 auth_service_.reset(new google_apis::AuthService(
336 oauth_service,
337 signin_manager->GetAuthenticatedAccountId(),
338 url_request_context_getter,
339 scopes));
340 auth_service_->StartAuthentication(base::Bind(
341 &FileManagerPrivateRequestWebStoreAccessTokenFunction::
342 OnAccessTokenFetched,
343 this));
345 return true;
348 void FileManagerPrivateRequestWebStoreAccessTokenFunction::OnAccessTokenFetched(
349 google_apis::DriveApiErrorCode code,
350 const std::string& access_token) {
351 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
353 if (code == google_apis::HTTP_SUCCESS) {
354 DCHECK(auth_service_->HasAccessToken());
355 DCHECK(access_token == auth_service_->access_token());
356 if (logger)
357 logger->Log(logging::LOG_INFO, "CWS OAuth token fetch succeeded.");
358 SetResult(new base::StringValue(access_token));
359 SendResponse(true);
360 } else {
361 if (logger) {
362 logger->Log(logging::LOG_ERROR,
363 "CWS OAuth token fetch failed. (DriveApiErrorCode: %s)",
364 google_apis::DriveApiErrorCodeToString(code).c_str());
366 SetResult(base::Value::CreateNullValue());
367 SendResponse(false);
371 bool FileManagerPrivateGetProfilesFunction::RunSync() {
372 const std::vector<linked_ptr<api::file_manager_private::ProfileInfo> >&
373 profiles = GetLoggedInProfileInfoList();
375 // Obtains the display profile ID.
376 AppWindow* const app_window = GetCurrentAppWindow(this);
377 chrome::MultiUserWindowManager* const window_manager =
378 chrome::MultiUserWindowManager::GetInstance();
379 const std::string current_profile_id =
380 multi_user_util::GetUserIDFromProfile(GetProfile());
381 const std::string display_profile_id =
382 window_manager && app_window ? window_manager->GetUserPresentingWindow(
383 app_window->GetNativeWindow())
384 : "";
386 results_ = api::file_manager_private::GetProfiles::Results::Create(
387 profiles,
388 current_profile_id,
389 display_profile_id.empty() ? current_profile_id : display_profile_id);
390 return true;
393 bool FileManagerPrivateOpenInspectorFunction::RunSync() {
394 using extensions::api::file_manager_private::OpenInspector::Params;
395 const scoped_ptr<Params> params(Params::Create(*args_));
396 EXTENSION_FUNCTION_VALIDATE(params);
398 switch (params->type) {
399 case extensions::api::file_manager_private::INSPECTION_TYPE_NORMAL:
400 // Open inspector for foreground page.
401 DevToolsWindow::OpenDevToolsWindow(
402 content::WebContents::FromRenderViewHost(render_view_host()));
403 break;
404 case extensions::api::file_manager_private::INSPECTION_TYPE_CONSOLE:
405 // Open inspector for foreground page and bring focus to the console.
406 DevToolsWindow::OpenDevToolsWindow(
407 content::WebContents::FromRenderViewHost(render_view_host()),
408 DevToolsToggleAction::ShowConsole());
409 break;
410 case extensions::api::file_manager_private::INSPECTION_TYPE_ELEMENT:
411 // Open inspector for foreground page in inspect element mode.
412 DevToolsWindow::OpenDevToolsWindow(
413 content::WebContents::FromRenderViewHost(render_view_host()),
414 DevToolsToggleAction::Inspect());
415 break;
416 case extensions::api::file_manager_private::INSPECTION_TYPE_BACKGROUND:
417 // Open inspector for background page.
418 extensions::devtools_util::InspectBackgroundPage(extension(),
419 GetProfile());
420 break;
421 default:
422 NOTREACHED();
423 SetError(
424 base::StringPrintf("Unexpected inspection type(%d) is specified.",
425 static_cast<int>(params->type)));
426 return false;
428 return true;
431 FileManagerPrivateGetMimeTypeFunction::FileManagerPrivateGetMimeTypeFunction() {
434 FileManagerPrivateGetMimeTypeFunction::
435 ~FileManagerPrivateGetMimeTypeFunction() {
438 bool FileManagerPrivateGetMimeTypeFunction::RunAsync() {
439 using extensions::api::file_manager_private::GetMimeType::Params;
440 const scoped_ptr<Params> params(Params::Create(*args_));
441 EXTENSION_FUNCTION_VALIDATE(params);
443 // Convert file url to local path.
444 const scoped_refptr<storage::FileSystemContext> file_system_context =
445 file_manager::util::GetFileSystemContextForRenderViewHost(
446 GetProfile(), render_view_host());
448 const GURL file_url(params->file_url);
449 storage::FileSystemURL file_system_url(
450 file_system_context->CrackURL(file_url));
452 app_file_handler_util::GetMimeTypeForLocalPath(
453 GetProfile(), file_system_url.path(),
454 base::Bind(&FileManagerPrivateGetMimeTypeFunction::OnGetMimeType, this));
456 return true;
459 void FileManagerPrivateGetMimeTypeFunction::OnGetMimeType(
460 const std::string& mimeType) {
461 SetResult(new base::StringValue(mimeType));
462 SendResponse(true);
465 ExtensionFunction::ResponseAction
466 FileManagerPrivateIsPiexLoaderEnabledFunction::Run() {
467 #if defined(OFFICIAL_BUILD)
468 return RespondNow(OneArgument(new base::FundamentalValue(true)));
469 #else
470 return RespondNow(OneArgument(new base::FundamentalValue(false)));
471 #endif
474 FileManagerPrivateGetProvidingExtensionsFunction::
475 FileManagerPrivateGetProvidingExtensionsFunction()
476 : chrome_details_(this) {
479 ExtensionFunction::ResponseAction
480 FileManagerPrivateGetProvidingExtensionsFunction::Run() {
481 using chromeos::file_system_provider::Service;
482 using chromeos::file_system_provider::ProvidingExtensionInfo;
483 const Service* const service = Service::Get(chrome_details_.GetProfile());
484 const std::vector<ProvidingExtensionInfo> info_list =
485 service->GetProvidingExtensionInfoList();
487 using api::file_manager_private::ProvidingExtension;
488 std::vector<linked_ptr<ProvidingExtension>> providing_extensions;
489 for (const auto& info : info_list) {
490 const linked_ptr<ProvidingExtension> providing_extension(
491 new ProvidingExtension);
492 providing_extension->extension_id = info.extension_id;
493 providing_extension->name = info.name;
494 providing_extension->can_configure = info.can_configure;
495 providing_extension->can_add = info.can_add;
496 providing_extensions.push_back(providing_extension);
499 return RespondNow(ArgumentList(
500 api::file_manager_private::GetProvidingExtensions::Results::Create(
501 providing_extensions).Pass()));
504 FileManagerPrivateAddProvidedFileSystemFunction::
505 FileManagerPrivateAddProvidedFileSystemFunction()
506 : chrome_details_(this) {
509 ExtensionFunction::ResponseAction
510 FileManagerPrivateAddProvidedFileSystemFunction::Run() {
511 using extensions::api::file_manager_private::AddProvidedFileSystem::Params;
512 const scoped_ptr<Params> params(Params::Create(*args_));
513 EXTENSION_FUNCTION_VALIDATE(params);
515 using chromeos::file_system_provider::Service;
516 using chromeos::file_system_provider::ProvidingExtensionInfo;
517 Service* const service = Service::Get(chrome_details_.GetProfile());
519 if (!service->RequestMount(params->extension_id))
520 return RespondNow(Error("Failed to request a new mount."));
522 return RespondNow(NoArguments());
525 FileManagerPrivateConfigureProvidedFileSystemFunction::
526 FileManagerPrivateConfigureProvidedFileSystemFunction()
527 : chrome_details_(this) {
530 ExtensionFunction::ResponseAction
531 FileManagerPrivateConfigureProvidedFileSystemFunction::Run() {
532 using extensions::api::file_manager_private::ConfigureProvidedFileSystem::
533 Params;
534 const scoped_ptr<Params> params(Params::Create(*args_));
535 EXTENSION_FUNCTION_VALIDATE(params);
537 using file_manager::VolumeManager;
538 using file_manager::Volume;
539 VolumeManager* const volume_manager =
540 VolumeManager::Get(chrome_details_.GetProfile());
541 LOG(ERROR) << "LOOKING FOR: " << params->volume_id;
542 base::WeakPtr<Volume> volume =
543 volume_manager->FindVolumeById(params->volume_id);
544 if (!volume.get())
545 return RespondNow(Error("Volume not found."));
547 using chromeos::file_system_provider::Service;
548 Service* const service = Service::Get(chrome_details_.GetProfile());
549 DCHECK(service);
551 using chromeos::file_system_provider::ProvidedFileSystemInterface;
552 ProvidedFileSystemInterface* const file_system =
553 service->GetProvidedFileSystem(volume->extension_id(),
554 volume->file_system_id());
555 DCHECK(file_system);
557 file_system->Configure(base::Bind(
558 &FileManagerPrivateConfigureProvidedFileSystemFunction::OnCompleted,
559 this));
560 return RespondLater();
563 void FileManagerPrivateConfigureProvidedFileSystemFunction::OnCompleted(
564 base::File::Error result) {
565 if (result != base::File::FILE_OK) {
566 Respond(Error("Failed to complete configuration."));
567 return;
570 Respond(NoArguments());
573 } // namespace extensions