private_api_drive.cc revision 4ad1aa43a48567659193a298fad74f55e00b3dd9
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. 4 5#include "chrome/browser/chromeos/extensions/file_manager/private_api_drive.h" 6 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" 23 24using content::BrowserThread; 25 26using file_manager::util::EntryDefinition; 27using file_manager::util::EntryDefinitionCallback; 28using file_manager::util::EntryDefinitionList; 29using file_manager::util::EntryDefinitionListCallback; 30using file_manager::util::FileDefinition; 31using file_manager::util::FileDefinitionList; 32 33namespace extensions { 34namespace { 35 36// List of connection types of drive. 37// Keep this in sync with the DriveConnectionType in common/js/util.js. 38const char kDriveConnectionTypeOffline[] = "offline"; 39const char kDriveConnectionTypeMetered[] = "metered"; 40const char kDriveConnectionTypeOnline[] = "online"; 41 42// List of reasons of kDriveConnectionType*. 43// Keep this in sync with the DriveConnectionReason in common/js/util.js. 44const char kDriveConnectionReasonNotReady[] = "not_ready"; 45const char kDriveConnectionReasonNoNetwork[] = "no_network"; 46const char kDriveConnectionReasonNoService[] = "no_service"; 47 48// Copies properties from |entry_proto| to |properties|. |shared_with_me| is 49// given from the running profile. 50void FillDriveEntryPropertiesValue( 51 const drive::ResourceEntry& entry_proto, 52 bool shared_with_me, 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())); 56 57 if (!entry_proto.has_file_specific_info()) 58 return; 59 60 const drive::FileSpecificInfo& file_specific_info = 61 entry_proto.file_specific_info(); 62 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())); 69 } 70 if (file_specific_info.has_image_height()) { 71 properties->image_height.reset( 72 new int(file_specific_info.image_height())); 73 } 74 if (file_specific_info.has_image_rotation()) { 75 properties->image_rotation.reset( 76 new int(file_specific_info.image_rotation())); 77 } 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())); 82} 83 84// Creates entry definition list for (metadata) search result info list. 85template <class T> 86void ConvertSearchResultInfoListToEntryDefinitionList( 87 Profile* profile, 88 const std::string& extension_id, 89 const std::vector<T>& search_result_info_list, 90 const EntryDefinitionListCallback& callback) { 91 FileDefinitionList file_definition_list; 92 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); 100 } 101 102 file_manager::util::ConvertFileDefinitionListToEntryDefinitionList( 103 profile, 104 extension_id, 105 file_definition_list, // Safe, since copied internally. 106 callback); 107} 108 109} // namespace 110 111FileBrowserPrivateGetDriveEntryPropertiesFunction:: 112 FileBrowserPrivateGetDriveEntryPropertiesFunction() 113 : properties_( 114 new extensions::api::file_browser_private::DriveEntryProperties) {} 115 116FileBrowserPrivateGetDriveEntryPropertiesFunction:: 117 ~FileBrowserPrivateGetDriveEntryPropertiesFunction() { 118} 119 120bool FileBrowserPrivateGetDriveEntryPropertiesFunction::RunImpl() { 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 122 123 using extensions::api::file_browser_private::GetDriveEntryProperties::Params; 124 const scoped_ptr<Params> params(Params::Create(*args_)); 125 EXTENSION_FUNCTION_VALIDATE(params); 126 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); 132 133 // Owner not found. 134 if (!file_owner_profile_) { 135 CompleteGetFileProperties(drive::FILE_ERROR_FAILED); 136 return true; 137 } 138 139 // Start getting the file info. 140 drive::FileSystemInterface* const file_system = 141 drive::util::GetFileSystemByProfile(file_owner_profile_); 142 if (!file_system) { 143 // |file_system| is NULL if Drive is disabled or not mounted. 144 CompleteGetFileProperties(drive::FILE_ERROR_FAILED); 145 return true; 146 } 147 148 file_system->GetResourceEntry( 149 file_path_, 150 base::Bind( 151 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetFileInfo, 152 this)); 153 return true; 154} 155 156void FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetFileInfo( 157 drive::FileError error, 158 scoped_ptr<drive::ResourceEntry> entry) { 159 if (error != drive::FILE_ERROR_OK) { 160 CompleteGetFileProperties(error); 161 return; 162 } 163 DCHECK(entry); 164 owner_resource_entry_.swap(entry); 165 166 if (GetProfile()->IsSameProfile(file_owner_profile_)) { 167 StartParseFileInfo(owner_resource_entry_->shared_with_me()); 168 return; 169 } 170 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()); 175 if (!file_system) { 176 CompleteGetFileProperties(drive::FILE_ERROR_FAILED); 177 return; 178 } 179 file_system->GetPathFromResourceId( 180 owner_resource_entry_->resource_id(), 181 base::Bind( 182 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetRunningPath, 183 this)); 184} 185 186void 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); 192 return; 193 } 194 195 drive::FileSystemInterface* const file_system = 196 drive::util::GetFileSystemByProfile(GetProfile()); 197 if (!file_system) { 198 // The drive is disable for the running profile. 199 StartParseFileInfo(false); 200 return; 201 } 202 file_system->GetResourceEntry( 203 file_path, 204 base::Bind( 205 &FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetShareInfo, 206 this)); 207} 208 209void FileBrowserPrivateGetDriveEntryPropertiesFunction::OnGetShareInfo( 210 drive::FileError error, 211 scoped_ptr<drive::ResourceEntry> entry) { 212 if (error != drive::FILE_ERROR_OK) { 213 CompleteGetFileProperties(error); 214 return; 215 } 216 DCHECK(entry); 217 StartParseFileInfo(entry->shared_with_me()); 218} 219 220void 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); 225 return; 226 } 227 228 FillDriveEntryPropertiesValue( 229 *owner_resource_entry_, shared_with_me, properties_.get()); 230 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); 238 return; 239 } 240 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); 245 return; 246 } 247 248 const drive::FileSpecificInfo& file_specific_info = 249 owner_resource_entry_->file_specific_info(); 250 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(), 256 &drive_apps); 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())); 274 } 275 } 276 } 277 278 file_system->GetCacheEntry( 279 file_path_, 280 base::Bind(&FileBrowserPrivateGetDriveEntryPropertiesFunction:: 281 CacheStateReceived, this)); 282} 283 284void FileBrowserPrivateGetDriveEntryPropertiesFunction::CacheStateReceived( 285 bool /* success */, 286 const drive::FileCacheEntry& cache_entry) { 287 // In case of an error (i.e. success is false), cache_entry.is_*() all 288 // returns false. 289 properties_->is_pinned.reset(new bool(cache_entry.is_pinned())); 290 properties_->is_present.reset(new bool(cache_entry.is_present())); 291 292 CompleteGetFileProperties(drive::FILE_ERROR_OK); 293} 294 295void FileBrowserPrivateGetDriveEntryPropertiesFunction:: 296 CompleteGetFileProperties(drive::FileError error) { 297 results_ = extensions::api::file_browser_private::GetDriveEntryProperties:: 298 Results::Create(*properties_); 299 SendResponse(true); 300} 301 302bool FileBrowserPrivatePinDriveFileFunction::RunImpl() { 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 304 305 using extensions::api::file_browser_private::PinDriveFile::Params; 306 const scoped_ptr<Params> params(Params::Create(*args_)); 307 EXTENSION_FUNCTION_VALIDATE(params); 308 309 drive::FileSystemInterface* const file_system = 310 drive::util::GetFileSystemByProfile(GetProfile()); 311 if (!file_system) // |file_system| is NULL if Drive is disabled. 312 return false; 313 314 const base::FilePath drive_path = 315 drive::util::ExtractDrivePath(file_manager::util::GetLocalPathFromURL( 316 render_view_host(), GetProfile(), GURL(params->file_url))); 317 if (params->pin) { 318 file_system->Pin(drive_path, 319 base::Bind(&FileBrowserPrivatePinDriveFileFunction:: 320 OnPinStateSet, this)); 321 } else { 322 file_system->Unpin(drive_path, 323 base::Bind(&FileBrowserPrivatePinDriveFileFunction:: 324 OnPinStateSet, this)); 325 } 326 return true; 327} 328 329void FileBrowserPrivatePinDriveFileFunction:: 330 OnPinStateSet(drive::FileError error) { 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 332 333 if (error == drive::FILE_ERROR_OK) { 334 SendResponse(true); 335 } else { 336 SetError(drive::FileErrorToString(error)); 337 SendResponse(false); 338 } 339} 340 341FileBrowserPrivateGetDriveFilesFunction:: 342 FileBrowserPrivateGetDriveFilesFunction() { 343} 344 345FileBrowserPrivateGetDriveFilesFunction:: 346 ~FileBrowserPrivateGetDriveFilesFunction() { 347} 348 349bool 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); 353 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); 361 } 362 363 GetFileOrSendResponse(); 364 return true; 365} 366 367void 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_); 372 SendResponse(true); 373 return; 374 } 375 376 // Get the file on the top of the queue. 377 base::FilePath drive_path = remaining_drive_paths_.front(); 378 379 drive::FileSystemInterface* file_system = 380 drive::util::GetFileSystemByProfile(GetProfile()); 381 if (!file_system) { 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>()); 385 return; 386 } 387 388 file_system->GetFile( 389 drive_path, 390 base::Bind(&FileBrowserPrivateGetDriveFilesFunction::OnFileReady, this)); 391} 392 393 394void 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(); 399 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(); 403 } else { 404 local_paths_.push_back(""); 405 DVLOG(1) << "Failed to get " << drive_path.value() 406 << " with error code: " << error; 407 } 408 409 remaining_drive_paths_.pop(); 410 411 // Start getting the next file. 412 GetFileOrSendResponse(); 413} 414 415bool 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); 419 420 drive::DriveIntegrationService* integration_service = 421 drive::DriveIntegrationServiceFactory::FindForProfile(GetProfile()); 422 if (!integration_service || !integration_service->IsMounted()) 423 return false; 424 425 // Create the mapping from file path to job ID. 426 drive::JobListInterface* job_list = integration_service->job_list(); 427 DCHECK(job_list); 428 std::vector<drive::JobInfo> jobs = job_list->GetJobInfoList(); 429 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); 435 } 436 437 // Cancel by 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()) 444 continue; 445 446 DCHECK(drive::util::IsUnderDriveMountPoint(file_path)); 447 file_path = drive::util::ExtractDrivePath(file_path); 448 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]); 454 } 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); 462 } 463 results_ = api::file_browser_private::CancelFileTransfers::Results::Create( 464 responses); 465 SendResponse(true); 466 return true; 467} 468 469bool 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); 473 474 drive::FileSystemInterface* const file_system = 475 drive::util::GetFileSystemByProfile(GetProfile()); 476 if (!file_system) { 477 // |file_system| is NULL if Drive is disabled. 478 return false; 479 } 480 481 file_system->Search( 482 params->search_params.query, GURL(params->search_params.next_feed), 483 base::Bind(&FileBrowserPrivateSearchDriveFunction::OnSearch, this)); 484 return true; 485} 486 487void FileBrowserPrivateSearchDriveFunction::OnSearch( 488 drive::FileError error, 489 const GURL& next_link, 490 scoped_ptr<SearchResultInfoList> results) { 491 if (error != drive::FILE_ERROR_OK) { 492 SendResponse(false); 493 return; 494 } 495 496 // Outlives the following conversion, since the pointer is bound to the 497 // callback. 498 DCHECK(results.get()); 499 const SearchResultInfoList& results_ref = *results.get(); 500 501 ConvertSearchResultInfoListToEntryDefinitionList( 502 GetProfile(), 503 extension_->id(), 504 results_ref, 505 base::Bind(&FileBrowserPrivateSearchDriveFunction::OnEntryDefinitionList, 506 this, 507 next_link, 508 base::Passed(&results))); 509} 510 511void 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(); 517 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(); 521 ++it) { 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); 528 } 529 530 base::DictionaryValue* result = new base::DictionaryValue(); 531 result->Set("entries", entries); 532 result->SetString("nextFeed", next_link.spec()); 533 534 SetResult(result); 535 SendResponse(true); 536} 537 538bool FileBrowserPrivateSearchDriveMetadataFunction::RunImpl() { 539 using api::file_browser_private::SearchDriveMetadata::Params; 540 const scoped_ptr<Params> params(Params::Create(*args_)); 541 EXTENSION_FUNCTION_VALIDATE(params); 542 543 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile()); 544 if (logger) { 545 logger->Log(logging::LOG_INFO, 546 "%s[%d] called. (types: '%s', maxResults: '%d')", 547 name().c_str(), 548 request_id(), 549 api::file_browser_private::ToString( 550 params->search_params.types).c_str(), 551 params->search_params.max_results); 552 } 553 set_log_on_completion(true); 554 555 drive::FileSystemInterface* const file_system = 556 drive::util::GetFileSystemByProfile(GetProfile()); 557 if (!file_system) { 558 // |file_system| is NULL if Drive is disabled. 559 return false; 560 } 561 562 int options = -1; 563 switch (params->search_params.types) { 564 case api::file_browser_private::SEARCH_TYPE_EXCLUDE_DIRECTORIES: 565 options = drive::SEARCH_METADATA_EXCLUDE_DIRECTORIES; 566 break; 567 case api::file_browser_private::SEARCH_TYPE_SHARED_WITH_ME: 568 options = drive::SEARCH_METADATA_SHARED_WITH_ME; 569 break; 570 case api::file_browser_private::SEARCH_TYPE_OFFLINE: 571 options = drive::SEARCH_METADATA_OFFLINE; 572 break; 573 case api::file_browser_private::SEARCH_TYPE_ALL: 574 options = drive::SEARCH_METADATA_ALL; 575 break; 576 case api::file_browser_private::SEARCH_TYPE_NONE: 577 break; 578 } 579 DCHECK_NE(options, -1); 580 581 file_system->SearchMetadata( 582 params->search_params.query, 583 options, 584 params->search_params.max_results, 585 base::Bind(&FileBrowserPrivateSearchDriveMetadataFunction:: 586 OnSearchMetadata, this)); 587 return true; 588} 589 590void FileBrowserPrivateSearchDriveMetadataFunction::OnSearchMetadata( 591 drive::FileError error, 592 scoped_ptr<drive::MetadataSearchResultVector> results) { 593 if (error != drive::FILE_ERROR_OK) { 594 SendResponse(false); 595 return; 596 } 597 598 // Outlives the following conversion, since the pointer is bound to the 599 // callback. 600 DCHECK(results.get()); 601 const drive::MetadataSearchResultVector& results_ref = *results.get(); 602 603 ConvertSearchResultInfoListToEntryDefinitionList( 604 GetProfile(), 605 extension_->id(), 606 results_ref, 607 base::Bind( 608 &FileBrowserPrivateSearchDriveMetadataFunction::OnEntryDefinitionList, 609 this, 610 base::Passed(&results))); 611} 612 613void 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(); 618 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(); 625 626 // FileEntry fields. 627 base::DictionaryValue* entry = new base::DictionaryValue(); 628 entry->SetString( 629 "fileSystemName", entry_definition_list->at(i).file_system_name); 630 entry->SetString( 631 "fileSystemRoot", entry_definition_list->at(i).file_system_root_url); 632 entry->SetString( 633 "fileFullPath", 634 "/" + entry_definition_list->at(i).full_path.AsUTF8Unsafe()); 635 entry->SetBoolean("fileIsDirectory", 636 entry_definition_list->at(i).is_directory); 637 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); 643 } 644 645 SetResult(results_list); 646 SendResponse(true); 647} 648 649bool FileBrowserPrivateGetDriveConnectionStateFunction::RunImpl() { 650 api::file_browser_private::DriveConnectionState result; 651 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)); 656 break; 657 case drive::util::DRIVE_DISCONNECTED_NONETWORK: 658 result.type = kDriveConnectionTypeOffline; 659 result.reason.reset(new std::string(kDriveConnectionReasonNoNetwork)); 660 break; 661 case drive::util::DRIVE_DISCONNECTED_NOTREADY: 662 result.type = kDriveConnectionTypeOffline; 663 result.reason.reset(new std::string(kDriveConnectionReasonNotReady)); 664 break; 665 case drive::util::DRIVE_CONNECTED_METERED: 666 result.type = kDriveConnectionTypeMetered; 667 break; 668 case drive::util::DRIVE_CONNECTED: 669 result.type = kDriveConnectionTypeOnline; 670 break; 671 } 672 673 results_ = api::file_browser_private::GetDriveConnectionState::Results:: 674 Create(result); 675 676 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile()); 677 if (logger) 678 logger->Log(logging::LOG_INFO, "%s succeeded.", name().c_str()); 679 return true; 680} 681 682bool 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); 686 687 drive::DriveServiceInterface* const drive_service = 688 drive::util::GetDriveServiceByProfile(GetProfile()); 689 690 if (!drive_service) { 691 // DriveService is not available. 692 SetResult(new base::StringValue("")); 693 SendResponse(true); 694 return true; 695 } 696 697 // If refreshing is requested, then clear the token to refetch it. 698 if (params->refresh) 699 drive_service->ClearAccessToken(); 700 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)); 706 return true; 707} 708 709void FileBrowserPrivateRequestAccessTokenFunction::OnAccessTokenFetched( 710 google_apis::GDataErrorCode code, 711 const std::string& access_token) { 712 SetResult(new base::StringValue(access_token)); 713 SendResponse(true); 714} 715 716bool 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); 720 721 const base::FilePath path = file_manager::util::GetLocalPathFromURL( 722 render_view_host(), GetProfile(), GURL(params->url)); 723 DCHECK(drive::util::IsUnderDriveMountPoint(path)); 724 725 const base::FilePath drive_path = drive::util::ExtractDrivePath(path); 726 727 drive::FileSystemInterface* const file_system = 728 drive::util::GetFileSystemByProfile(GetProfile()); 729 if (!file_system) { 730 // |file_system| is NULL if Drive is disabled. 731 return false; 732 } 733 734 file_system->GetShareUrl( 735 drive_path, 736 file_manager::util::GetFileManagerBaseUrl(), // embed origin 737 base::Bind(&FileBrowserPrivateGetShareUrlFunction::OnGetShareUrl, this)); 738 return true; 739} 740 741void 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."); 746 SendResponse(false); 747 return; 748 } 749 750 SetResult(new base::StringValue(share_url.spec())); 751 SendResponse(true); 752} 753 754bool 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); 758 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); 763 764 if (!owner_profile) 765 return false; 766 767 drive::FileSystemInterface* const owner_file_system = 768 drive::util::GetFileSystemByProfile(owner_profile); 769 if (!owner_file_system) 770 return false; 771 772 const chromeos::User* const user = 773 chromeos::UserManager::Get()->GetUserByProfile(GetProfile()); 774 if (!user || !user->is_logged_in()) 775 return false; 776 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: 781 NOTREACHED(); 782 return false; 783 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_EDIT: 784 role = google_apis::drive::PERMISSION_ROLE_WRITER; 785 break; 786 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_COMMENT: 787 role = google_apis::drive::PERMISSION_ROLE_COMMENTER; 788 break; 789 case api::file_browser_private::DRIVE_SHARE_TYPE_CAN_VIEW: 790 role = google_apis::drive::PERMISSION_ROLE_READER; 791 break; 792 } 793 794 // Share |drive_path| in |owner_file_system| to |user->email()|. 795 owner_file_system->AddPermission( 796 drive_path, 797 user->email(), 798 role, 799 base::Bind(&FileBrowserPrivateRequestDriveShareFunction::OnAddPermission, 800 this)); 801 return true; 802} 803 804void FileBrowserPrivateRequestDriveShareFunction::OnAddPermission( 805 drive::FileError error) { 806 SendResponse(error == drive::FILE_ERROR_OK); 807} 808 809} // namespace extensions 810