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_drive.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
9 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
10 #include "chrome/browser/chromeos/file_manager/file_tasks.h"
11 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
12 #include "chrome/browser/chromeos/file_manager/url_util.h"
13 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
14 #include "chrome/browser/chromeos/login/user_manager.h"
15 #include "chrome/browser/drive/drive_app_registry.h"
16 #include "chrome/browser/drive/event_logger.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/extensions/api/file_browser_private.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "webkit/common/fileapi/file_system_info.h"
22 #include "webkit/common/fileapi/file_system_util.h"
24 using content::BrowserThread;
26 using file_manager::util::EntryDefinition;
27 using file_manager::util::EntryDefinitionCallback;
28 using file_manager::util::EntryDefinitionList;
29 using file_manager::util::EntryDefinitionListCallback;
30 using file_manager::util::FileDefinition;
31 using file_manager::util::FileDefinitionList;
33 namespace extensions {
36 // List of connection types of drive.
37 // Keep this in sync with the DriveConnectionType in common/js/util.js.
38 const char kDriveConnectionTypeOffline[] = "offline";
39 const char kDriveConnectionTypeMetered[] = "metered";
40 const char kDriveConnectionTypeOnline[] = "online";
42 // List of reasons of kDriveConnectionType*.
43 // Keep this in sync with the DriveConnectionReason in common/js/util.js.
44 const char kDriveConnectionReasonNotReady[] = "not_ready";
45 const char kDriveConnectionReasonNoNetwork[] = "no_network";
46 const char kDriveConnectionReasonNoService[] = "no_service";
48 // Copies properties from |entry_proto| to |properties|. |shared_with_me| is
49 // given from the running profile.
50 void FillDriveEntryPropertiesValue(
51 const drive::ResourceEntry& entry_proto,
53 api::file_browser_private::DriveEntryProperties* properties) {
54 properties->shared_with_me.reset(new bool(shared_with_me));
55 properties->shared.reset(new bool(entry_proto.shared()));
57 if (!entry_proto.has_file_specific_info())
60 const drive::FileSpecificInfo& file_specific_info =
61 entry_proto.file_specific_info();
63 properties->thumbnail_url.reset(
64 new std::string("https://www.googledrive.com/thumb/" +
65 entry_proto.resource_id() + "?width=500&height=500"));
66 if (file_specific_info.has_image_width()) {
67 properties->image_width.reset(
68 new int(file_specific_info.image_width()));
70 if (file_specific_info.has_image_height()) {
71 properties->image_height.reset(
72 new int(file_specific_info.image_height()));
74 if (file_specific_info.has_image_rotation()) {
75 properties->image_rotation.reset(
76 new int(file_specific_info.image_rotation()));
78 properties->is_hosted.reset(
79 new bool(file_specific_info.is_hosted_document()));
80 properties->content_mime_type.reset(
81 new std::string(file_specific_info.content_mime_type()));
84 // Creates entry definition list for (metadata) search result info list.
86 void ConvertSearchResultInfoListToEntryDefinitionList(
88 const std::string& extension_id,
89 const std::vector<T>& search_result_info_list,
90 const EntryDefinitionListCallback& callback) {
91 FileDefinitionList file_definition_list;
93 for (size_t i = 0; i < search_result_info_list.size(); ++i) {
94 FileDefinition file_definition;
95 file_definition.virtual_path =
96 file_manager::util::ConvertDrivePathToRelativeFileSystemPath(
97 profile, extension_id, search_result_info_list.at(i).path);
98 file_definition.is_directory = search_result_info_list.at(i).is_directory;
99 file_definition_list.push_back(file_definition);
102 file_manager::util::ConvertFileDefinitionListToEntryDefinitionList(
105 file_definition_list, // Safe, since copied internally.
111 FileBrowserPrivateGetDriveEntryPropertiesFunction::
112 FileBrowserPrivateGetDriveEntryPropertiesFunction()
114 new extensions::api::file_browser_private::DriveEntryProperties) {}
116 FileBrowserPrivateGetDriveEntryPropertiesFunction::
117 ~FileBrowserPrivateGetDriveEntryPropertiesFunction() {
120 bool FileBrowserPrivateGetDriveEntryPropertiesFunction::RunImpl() {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 using extensions::api::file_browser_private::GetDriveEntryProperties::Params;
124 const scoped_ptr<Params> params(Params::Create(*args_));
125 EXTENSION_FUNCTION_VALIDATE(params);
127 const GURL file_url = GURL(params->file_url);
128 const base::FilePath local_path = file_manager::util::GetLocalPathFromURL(
129 render_view_host(), GetProfile(), file_url);
130 file_path_ = drive::util::ExtractDrivePath(local_path);
131 file_owner_profile_ = drive::util::ExtractProfileFromPath(local_path);
134 if (!file_owner_profile_) {
135 CompleteGetFileProperties(drive::FILE_ERROR_FAILED);
139 // Start getting the file info.
140 drive::FileSystemInterface* const file_system =
141 drive::util::GetFileSystemByProfile(file_owner_profile_);
143 // |file_system| is NULL if Drive is disabled or not mounted.
144 CompleteGetFileProperties(drive::FILE_ERROR_FAILED);
148 file_system->GetResourceEntry(
151 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetFileInfo,
156 void FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetFileInfo(
157 drive::FileError error,
158 scoped_ptr<drive::ResourceEntry> entry) {
159 if (error != drive::FILE_ERROR_OK) {
160 CompleteGetFileProperties(error);
164 owner_resource_entry_.swap(entry);
166 if (GetProfile()->IsSameProfile(file_owner_profile_)) {
167 StartParseFileInfo(owner_resource_entry_->shared_with_me());
171 // If the running profile does not own the file, obtain the shared_with_me
172 // flag from the running profile's value.
173 drive::FileSystemInterface* const file_system =
174 drive::util::GetFileSystemByProfile(GetProfile());
176 CompleteGetFileProperties(drive::FILE_ERROR_FAILED);
179 file_system->GetPathFromResourceId(
180 owner_resource_entry_->resource_id(),
182 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetRunningPath,
186 void FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetRunningPath(
187 drive::FileError error,
188 const base::FilePath& file_path) {
189 if (error != drive::FILE_ERROR_OK) {
190 // The running profile does not know the file.
191 StartParseFileInfo(false);
195 drive::FileSystemInterface* const file_system =
196 drive::util::GetFileSystemByProfile(GetProfile());
198 // The drive is disable for the running profile.
199 StartParseFileInfo(false);
202 file_system->GetResourceEntry(
205 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetShareInfo,
209 void FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetShareInfo(
210 drive::FileError error,
211 scoped_ptr<drive::ResourceEntry> entry) {
212 if (error != drive::FILE_ERROR_OK) {
213 CompleteGetFileProperties(error);
217 StartParseFileInfo(entry->shared_with_me());
220 void FileBrowserPrivateGetDriveEntryPropertiesFunction::StartParseFileInfo(
221 bool shared_with_me) {
222 if (!g_browser_process->profile_manager()->IsValidProfile(
223 file_owner_profile_)) {
224 CompleteGetFileProperties(drive::FILE_ERROR_FAILED);
228 FillDriveEntryPropertiesValue(
229 *owner_resource_entry_, shared_with_me, properties_.get());
231 drive::FileSystemInterface* const file_system =
232 drive::util::GetFileSystemByProfile(file_owner_profile_);
233 drive::DriveAppRegistry* const app_registry =
234 drive::util::GetDriveAppRegistryByProfile(file_owner_profile_);
235 if (!file_system || !app_registry) {
236 // |file_system| or |app_registry| is NULL if Drive is disabled.
237 CompleteGetFileProperties(drive::FILE_ERROR_FAILED);
241 // The properties meaningful for directories are already filled in
242 // FillDriveEntryPropertiesValue().
243 if (!owner_resource_entry_->has_file_specific_info()) {
244 CompleteGetFileProperties(drive::FILE_ERROR_OK);
248 const drive::FileSpecificInfo& file_specific_info =
249 owner_resource_entry_->file_specific_info();
251 // Get drive WebApps that can accept this file. We just need to extract the
252 // doc icon for the drive app, which is set as default.
253 std::vector<drive::DriveAppInfo> drive_apps;
254 app_registry->GetAppsForFile(file_path_.Extension(),
255 file_specific_info.content_mime_type(),
257 if (!drive_apps.empty()) {
258 std::string default_task_id =
259 file_manager::file_tasks::GetDefaultTaskIdFromPrefs(
260 *file_owner_profile_->GetPrefs(),
261 file_specific_info.content_mime_type(),
262 file_path_.Extension());
263 file_manager::file_tasks::TaskDescriptor default_task;
264 file_manager::file_tasks::ParseTaskID(default_task_id, &default_task);
265 DCHECK(default_task_id.empty() || !default_task.app_id.empty());
266 for (size_t i = 0; i < drive_apps.size(); ++i) {
267 const drive::DriveAppInfo& app_info = drive_apps[i];
268 if (default_task.app_id == app_info.app_id) {
269 // The drive app is set as default. Files.app should use the doc icon.
270 const GURL doc_icon =
271 drive::util::FindPreferredIcon(app_info.document_icons,
272 drive::util::kPreferredIconSize);
273 properties_->custom_icon_url.reset(new std::string(doc_icon.spec()));
278 file_system->GetCacheEntry(
280 base::Bind(&FileBrowserPrivateGetDriveEntryPropertiesFunction::
281 CacheStateReceived, this));
284 void FileBrowserPrivateGetDriveEntryPropertiesFunction::CacheStateReceived(
286 const drive::FileCacheEntry& cache_entry) {
287 // In case of an error (i.e. success is false), cache_entry.is_*() all
289 properties_->is_pinned.reset(new bool(cache_entry.is_pinned()));
290 properties_->is_present.reset(new bool(cache_entry.is_present()));
292 CompleteGetFileProperties(drive::FILE_ERROR_OK);
295 void FileBrowserPrivateGetDriveEntryPropertiesFunction::
296 CompleteGetFileProperties(drive::FileError error) {
297 results_ = extensions::api::file_browser_private::GetDriveEntryProperties::
298 Results::Create(*properties_);
302 bool FileBrowserPrivatePinDriveFileFunction::RunImpl() {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
305 using extensions::api::file_browser_private::PinDriveFile::Params;
306 const scoped_ptr<Params> params(Params::Create(*args_));
307 EXTENSION_FUNCTION_VALIDATE(params);
309 drive::FileSystemInterface* const file_system =
310 drive::util::GetFileSystemByProfile(GetProfile());
311 if (!file_system) // |file_system| is NULL if Drive is disabled.
314 const base::FilePath drive_path =
315 drive::util::ExtractDrivePath(file_manager::util::GetLocalPathFromURL(
316 render_view_host(), GetProfile(), GURL(params->file_url)));
318 file_system->Pin(drive_path,
319 base::Bind(&FileBrowserPrivatePinDriveFileFunction::
320 OnPinStateSet, this));
322 file_system->Unpin(drive_path,
323 base::Bind(&FileBrowserPrivatePinDriveFileFunction::
324 OnPinStateSet, this));
329 void FileBrowserPrivatePinDriveFileFunction::
330 OnPinStateSet(drive::FileError error) {
331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
333 if (error == drive::FILE_ERROR_OK) {
336 SetError(drive::FileErrorToString(error));
341 FileBrowserPrivateGetDriveFilesFunction::
342 FileBrowserPrivateGetDriveFilesFunction() {
345 FileBrowserPrivateGetDriveFilesFunction::
346 ~FileBrowserPrivateGetDriveFilesFunction() {
349 bool FileBrowserPrivateGetDriveFilesFunction::RunImpl() {
350 using extensions::api::file_browser_private::GetDriveFiles::Params;
351 const scoped_ptr<Params> params(Params::Create(*args_));
352 EXTENSION_FUNCTION_VALIDATE(params);
354 // Convert the list of strings to a list of GURLs.
355 for (size_t i = 0; i < params->file_urls.size(); ++i) {
356 const base::FilePath path = file_manager::util::GetLocalPathFromURL(
357 render_view_host(), GetProfile(), GURL(params->file_urls[i]));
358 DCHECK(drive::util::IsUnderDriveMountPoint(path));
359 base::FilePath drive_path = drive::util::ExtractDrivePath(path);
360 remaining_drive_paths_.push(drive_path);
363 GetFileOrSendResponse();
367 void FileBrowserPrivateGetDriveFilesFunction::GetFileOrSendResponse() {
368 // Send the response if all files are obtained.
369 if (remaining_drive_paths_.empty()) {
370 results_ = extensions::api::file_browser_private::
371 GetDriveFiles::Results::Create(local_paths_);
376 // Get the file on the top of the queue.
377 base::FilePath drive_path = remaining_drive_paths_.front();
379 drive::FileSystemInterface* file_system =
380 drive::util::GetFileSystemByProfile(GetProfile());
382 // |file_system| is NULL if Drive is disabled or not mounted.
383 OnFileReady(drive::FILE_ERROR_FAILED, drive_path,
384 scoped_ptr<drive::ResourceEntry>());
388 file_system->GetFile(
390 base::Bind(&FileBrowserPrivateGetDriveFilesFunction::OnFileReady, this));
394 void FileBrowserPrivateGetDriveFilesFunction::OnFileReady(
395 drive::FileError error,
396 const base::FilePath& local_path,
397 scoped_ptr<drive::ResourceEntry> entry) {
398 base::FilePath drive_path = remaining_drive_paths_.front();
400 if (error == drive::FILE_ERROR_OK) {
401 local_paths_.push_back(local_path.AsUTF8Unsafe());
402 DVLOG(1) << "Got " << drive_path.value() << " as " << local_path.value();
404 local_paths_.push_back("");
405 DVLOG(1) << "Failed to get " << drive_path.value()
406 << " with error code: " << error;
409 remaining_drive_paths_.pop();
411 // Start getting the next file.
412 GetFileOrSendResponse();
415 bool FileBrowserPrivateCancelFileTransfersFunction::RunImpl() {
416 using extensions::api::file_browser_private::CancelFileTransfers::Params;
417 const scoped_ptr<Params> params(Params::Create(*args_));
418 EXTENSION_FUNCTION_VALIDATE(params);
420 drive::DriveIntegrationService* integration_service =
421 drive::DriveIntegrationServiceFactory::FindForProfile(GetProfile());
422 if (!integration_service || !integration_service->IsMounted())
425 // Create the mapping from file path to job ID.
426 drive::JobListInterface* job_list = integration_service->job_list();
428 std::vector<drive::JobInfo> jobs = job_list->GetJobInfoList();
430 typedef std::map<base::FilePath, std::vector<drive::JobID> > PathToIdMap;
431 PathToIdMap path_to_id_map;
432 for (size_t i = 0; i < jobs.size(); ++i) {
433 if (drive::IsActiveFileTransferJobInfo(jobs[i]))
434 path_to_id_map[jobs[i].file_path].push_back(jobs[i].job_id);
438 std::vector<linked_ptr<api::file_browser_private::
439 FileTransferCancelStatus> > responses;
440 for (size_t i = 0; i < params->file_urls.size(); ++i) {
441 base::FilePath file_path = file_manager::util::GetLocalPathFromURL(
442 render_view_host(), GetProfile(), GURL(params->file_urls[i]));
443 if (file_path.empty())
446 DCHECK(drive::util::IsUnderDriveMountPoint(file_path));
447 file_path = drive::util::ExtractDrivePath(file_path);
449 // Cancel all the jobs for the file.
450 PathToIdMap::iterator it = path_to_id_map.find(file_path);
451 if (it != path_to_id_map.end()) {
452 for (size_t i = 0; i < it->second.size(); ++i)
453 job_list->CancelJob(it->second[i]);
455 linked_ptr<api::file_browser_private::FileTransferCancelStatus> result(
456 new api::file_browser_private::FileTransferCancelStatus);
457 result->canceled = it != path_to_id_map.end();
458 // TODO(kinaba): simplify cancelFileTransfer() to take single URL each time,
459 // and eliminate this field; it is just returning a copy of the argument.
460 result->file_url = params->file_urls[i];
461 responses.push_back(result);
463 results_ = api::file_browser_private::CancelFileTransfers::Results::Create(
469 bool FileBrowserPrivateSearchDriveFunction::RunImpl() {
470 using extensions::api::file_browser_private::SearchDrive::Params;
471 const scoped_ptr<Params> params(Params::Create(*args_));
472 EXTENSION_FUNCTION_VALIDATE(params);
474 drive::FileSystemInterface* const file_system =
475 drive::util::GetFileSystemByProfile(GetProfile());
477 // |file_system| is NULL if Drive is disabled.
482 params->search_params.query, GURL(params->search_params.next_feed),
483 base::Bind(&FileBrowserPrivateSearchDriveFunction::OnSearch, this));
487 void FileBrowserPrivateSearchDriveFunction::OnSearch(
488 drive::FileError error,
489 const GURL& next_link,
490 scoped_ptr<SearchResultInfoList> results) {
491 if (error != drive::FILE_ERROR_OK) {
496 // Outlives the following conversion, since the pointer is bound to the
498 DCHECK(results.get());
499 const SearchResultInfoList& results_ref = *results.get();
501 ConvertSearchResultInfoListToEntryDefinitionList(
505 base::Bind(&FileBrowserPrivateSearchDriveFunction::OnEntryDefinitionList,
508 base::Passed(&results)));
511 void FileBrowserPrivateSearchDriveFunction::OnEntryDefinitionList(
512 const GURL& next_link,
513 scoped_ptr<SearchResultInfoList> search_result_info_list,
514 scoped_ptr<EntryDefinitionList> entry_definition_list) {
515 DCHECK_EQ(search_result_info_list->size(), entry_definition_list->size());
516 base::ListValue* entries = new base::ListValue();
518 // Convert Drive files to something File API stack can understand.
519 for (EntryDefinitionList::const_iterator it = entry_definition_list->begin();
520 it != entry_definition_list->end();
522 base::DictionaryValue* entry = new base::DictionaryValue();
523 entry->SetString("fileSystemName", it->file_system_name);
524 entry->SetString("fileSystemRoot", it->file_system_root_url);
525 entry->SetString("fileFullPath", "/" + it->full_path.AsUTF8Unsafe());
526 entry->SetBoolean("fileIsDirectory", it->is_directory);
527 entries->Append(entry);
530 base::DictionaryValue* result = new base::DictionaryValue();
531 result->Set("entries", entries);
532 result->SetString("nextFeed", next_link.spec());
538 bool FileBrowserPrivateSearchDriveMetadataFunction::RunImpl() {
539 using api::file_browser_private::SearchDriveMetadata::Params;
540 const scoped_ptr<Params> params(Params::Create(*args_));
541 EXTENSION_FUNCTION_VALIDATE(params);
543 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
545 logger->Log(logging::LOG_INFO,
546 "%s[%d] called. (types: '%s', maxResults: '%d')",
549 api::file_browser_private::ToString(
550 params->search_params.types).c_str(),
551 params->search_params.max_results);
553 set_log_on_completion(true);
555 drive::FileSystemInterface* const file_system =
556 drive::util::GetFileSystemByProfile(GetProfile());
558 // |file_system| is NULL if Drive is disabled.
563 switch (params->search_params.types) {
564 case api::file_browser_private::SEARCH_TYPE_EXCLUDE_DIRECTORIES:
565 options = drive::SEARCH_METADATA_EXCLUDE_DIRECTORIES;
567 case api::file_browser_private::SEARCH_TYPE_SHARED_WITH_ME:
568 options = drive::SEARCH_METADATA_SHARED_WITH_ME;
570 case api::file_browser_private::SEARCH_TYPE_OFFLINE:
571 options = drive::SEARCH_METADATA_OFFLINE;
573 case api::file_browser_private::SEARCH_TYPE_ALL:
574 options = drive::SEARCH_METADATA_ALL;
576 case api::file_browser_private::SEARCH_TYPE_NONE:
579 DCHECK_NE(options, -1);
581 file_system->SearchMetadata(
582 params->search_params.query,
584 params->search_params.max_results,
585 base::Bind(&FileBrowserPrivateSearchDriveMetadataFunction::
586 OnSearchMetadata, this));
590 void FileBrowserPrivateSearchDriveMetadataFunction::OnSearchMetadata(
591 drive::FileError error,
592 scoped_ptr<drive::MetadataSearchResultVector> results) {
593 if (error != drive::FILE_ERROR_OK) {
598 // Outlives the following conversion, since the pointer is bound to the
600 DCHECK(results.get());
601 const drive::MetadataSearchResultVector& results_ref = *results.get();
603 ConvertSearchResultInfoListToEntryDefinitionList(
608 &FileBrowserPrivateSearchDriveMetadataFunction::OnEntryDefinitionList,
610 base::Passed(&results)));
613 void FileBrowserPrivateSearchDriveMetadataFunction::OnEntryDefinitionList(
614 scoped_ptr<drive::MetadataSearchResultVector> search_result_info_list,
615 scoped_ptr<EntryDefinitionList> entry_definition_list) {
616 DCHECK_EQ(search_result_info_list->size(), entry_definition_list->size());
617 base::ListValue* results_list = new base::ListValue();
619 // Convert Drive files to something File API stack can understand. See
620 // file_browser_handler_custom_bindings.cc and
621 // file_browser_private_custom_bindings.js for how this is magically
622 // converted to a FileEntry.
623 for (size_t i = 0; i < entry_definition_list->size(); ++i) {
624 base::DictionaryValue* result_dict = new base::DictionaryValue();
627 base::DictionaryValue* entry = new base::DictionaryValue();
629 "fileSystemName", entry_definition_list->at(i).file_system_name);
631 "fileSystemRoot", entry_definition_list->at(i).file_system_root_url);
634 "/" + entry_definition_list->at(i).full_path.AsUTF8Unsafe());
635 entry->SetBoolean("fileIsDirectory",
636 entry_definition_list->at(i).is_directory);
638 result_dict->Set("entry", entry);
639 result_dict->SetString(
640 "highlightedBaseName",
641 search_result_info_list->at(i).highlighted_base_name);
642 results_list->Append(result_dict);
645 SetResult(results_list);
649 bool FileBrowserPrivateGetDriveConnectionStateFunction::RunImpl() {
650 api::file_browser_private::DriveConnectionState result;
652 switch (drive::util::GetDriveConnectionStatus(GetProfile())) {
653 case drive::util::DRIVE_DISCONNECTED_NOSERVICE:
654 result.type = kDriveConnectionTypeOffline;
655 result.reason.reset(new std::string(kDriveConnectionReasonNoService));
657 case drive::util::DRIVE_DISCONNECTED_NONETWORK:
658 result.type = kDriveConnectionTypeOffline;
659 result.reason.reset(new std::string(kDriveConnectionReasonNoNetwork));
661 case drive::util::DRIVE_DISCONNECTED_NOTREADY:
662 result.type = kDriveConnectionTypeOffline;
663 result.reason.reset(new std::string(kDriveConnectionReasonNotReady));
665 case drive::util::DRIVE_CONNECTED_METERED:
666 result.type = kDriveConnectionTypeMetered;
668 case drive::util::DRIVE_CONNECTED:
669 result.type = kDriveConnectionTypeOnline;
673 results_ = api::file_browser_private::GetDriveConnectionState::Results::
676 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
678 logger->Log(logging::LOG_INFO, "%s succeeded.", name().c_str());
682 bool FileBrowserPrivateRequestAccessTokenFunction::RunImpl() {
683 using extensions::api::file_browser_private::RequestAccessToken::Params;
684 const scoped_ptr<Params> params(Params::Create(*args_));
685 EXTENSION_FUNCTION_VALIDATE(params);
687 drive::DriveServiceInterface* const drive_service =
688 drive::util::GetDriveServiceByProfile(GetProfile());
690 if (!drive_service) {
691 // DriveService is not available.
692 SetResult(new base::StringValue(""));
697 // If refreshing is requested, then clear the token to refetch it.
699 drive_service->ClearAccessToken();
701 // Retrieve the cached auth token (if available), otherwise the AuthService
702 // instance will try to refetch it.
703 drive_service->RequestAccessToken(
704 base::Bind(&FileBrowserPrivateRequestAccessTokenFunction::
705 OnAccessTokenFetched, this));
709 void FileBrowserPrivateRequestAccessTokenFunction::OnAccessTokenFetched(
710 google_apis::GDataErrorCode code,
711 const std::string& access_token) {
712 SetResult(new base::StringValue(access_token));
716 bool FileBrowserPrivateGetShareUrlFunction::RunImpl() {
717 using extensions::api::file_browser_private::GetShareUrl::Params;
718 const scoped_ptr<Params> params(Params::Create(*args_));
719 EXTENSION_FUNCTION_VALIDATE(params);
721 const base::FilePath path = file_manager::util::GetLocalPathFromURL(
722 render_view_host(), GetProfile(), GURL(params->url));
723 DCHECK(drive::util::IsUnderDriveMountPoint(path));
725 const base::FilePath drive_path = drive::util::ExtractDrivePath(path);
727 drive::FileSystemInterface* const file_system =
728 drive::util::GetFileSystemByProfile(GetProfile());
730 // |file_system| is NULL if Drive is disabled.
734 file_system->GetShareUrl(
736 file_manager::util::GetFileManagerBaseUrl(), // embed origin
737 base::Bind(&FileBrowserPrivateGetShareUrlFunction::OnGetShareUrl, this));
741 void FileBrowserPrivateGetShareUrlFunction::OnGetShareUrl(
742 drive::FileError error,
743 const GURL& share_url) {
744 if (error != drive::FILE_ERROR_OK) {
745 SetError("Share Url for this item is not available.");
750 SetResult(new base::StringValue(share_url.spec()));
754 bool FileBrowserPrivateRequestDriveShareFunction::RunImpl() {
755 using extensions::api::file_browser_private::RequestDriveShare::Params;
756 const scoped_ptr<Params> params(Params::Create(*args_));
757 EXTENSION_FUNCTION_VALIDATE(params);
759 const base::FilePath path = file_manager::util::GetLocalPathFromURL(
760 render_view_host(), GetProfile(), GURL(params->url));
761 const base::FilePath drive_path = drive::util::ExtractDrivePath(path);
762 Profile* const owner_profile = drive::util::ExtractProfileFromPath(path);
767 drive::FileSystemInterface* const owner_file_system =
768 drive::util::GetFileSystemByProfile(owner_profile);
769 if (!owner_file_system)
772 const chromeos::User* const user =
773 chromeos::UserManager::Get()->GetUserByProfile(GetProfile());
774 if (!user || !user->is_logged_in())
777 google_apis::drive::PermissionRole role =
778 google_apis::drive::PERMISSION_ROLE_READER;
779 switch (params->share_type) {
780 case api::file_browser_private::DRIVE_SHARE_TYPE_NONE:
783 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_EDIT:
784 role = google_apis::drive::PERMISSION_ROLE_WRITER;
786 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_COMMENT:
787 role = google_apis::drive::PERMISSION_ROLE_COMMENTER;
789 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_VIEW:
790 role = google_apis::drive::PERMISSION_ROLE_READER;
794 // Share |drive_path| in |owner_file_system| to |user->email()|.
795 owner_file_system->AddPermission(
799 base::Bind(&FileBrowserPrivateRequestDriveShareFunction::OnAddPermission,
804 void FileBrowserPrivateRequestDriveShareFunction::OnAddPermission(
805 drive::FileError error) {
806 SendResponse(error == drive::FILE_ERROR_OK);
809 } // namespace extensions