private_api_drive.cc revision 3551c9c881056c480085172ff9840cab31610854
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 "base/prefs/pref_service.h" 8#include "base/strings/stringprintf.h" 9#include "chrome/browser/chromeos/drive/drive_app_registry.h" 10#include "chrome/browser/chromeos/drive/drive_integration_service.h" 11#include "chrome/browser/chromeos/drive/logging.h" 12#include "chrome/browser/chromeos/extensions/file_manager/file_tasks.h" 13#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" 14#include "chrome/browser/chromeos/extensions/file_manager/url_util.h" 15#include "chrome/browser/chromeos/fileapi/file_system_backend.h" 16#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/common/pref_names.h" 19#include "content/public/browser/browser_thread.h" 20#include "content/public/browser/render_view_host.h" 21#include "webkit/common/fileapi/file_system_util.h" 22 23using content::BrowserThread; 24 25namespace file_manager { 26namespace { 27 28// List of connection types of drive. 29// Keep this in sync with the DriveConnectionType in volume_manager.js. 30const char kDriveConnectionTypeOffline[] = "offline"; 31const char kDriveConnectionTypeMetered[] = "metered"; 32const char kDriveConnectionTypeOnline[] = "online"; 33 34 35// List of reasons of kDriveConnectionType*. 36// Keep this in sync with the DriveConnectionReason in volume_manager.js. 37const char kDriveConnectionReasonNotReady[] = "not_ready"; 38const char kDriveConnectionReasonNoNetwork[] = "no_network"; 39const char kDriveConnectionReasonNoService[] = "no_service"; 40 41// Does nothing with a bool parameter. Used as a placeholder for calling 42// ClearCacheAndRemountFileSystem(). TODO(yoshiki): Handle an error from 43// ClearCacheAndRemountFileSystem() properly: http://crbug.com/140511. 44void DoNothingWithBool(bool /* success */) { 45} 46 47// Copies properties from |entry_proto| to |property_dict|. 48void FillDriveEntryPropertiesValue( 49 const drive::ResourceEntry& entry_proto, 50 DictionaryValue* property_dict) { 51 property_dict->SetBoolean("sharedWithMe", entry_proto.shared_with_me()); 52 53 if (!entry_proto.has_file_specific_info()) 54 return; 55 56 const drive::FileSpecificInfo& file_specific_info = 57 entry_proto.file_specific_info(); 58 59 property_dict->SetString("thumbnailUrl", file_specific_info.thumbnail_url()); 60 property_dict->SetBoolean("isHosted", 61 file_specific_info.is_hosted_document()); 62 property_dict->SetString("contentMimeType", 63 file_specific_info.content_mime_type()); 64} 65 66} // namespace 67 68GetDriveEntryPropertiesFunction::GetDriveEntryPropertiesFunction() { 69} 70 71GetDriveEntryPropertiesFunction::~GetDriveEntryPropertiesFunction() { 72} 73 74bool GetDriveEntryPropertiesFunction::RunImpl() { 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 76 77 std::string file_url_str; 78 if (args_->GetSize() != 1 || !args_->GetString(0, &file_url_str)) 79 return false; 80 81 GURL file_url = GURL(file_url_str); 82 file_path_ = drive::util::ExtractDrivePath( 83 util::GetLocalPathFromURL(render_view_host(), profile(), file_url)); 84 85 properties_.reset(new base::DictionaryValue); 86 properties_->SetString("fileUrl", file_url.spec()); 87 88 // Start getting the file info. 89 drive::DriveIntegrationService* integration_service = 90 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 91 // |integration_service| is NULL if Drive is disabled. 92 if (!integration_service) { 93 CompleteGetFileProperties(drive::FILE_ERROR_FAILED); 94 return true; 95 } 96 97 integration_service->file_system()->GetResourceEntryByPath( 98 file_path_, 99 base::Bind(&GetDriveEntryPropertiesFunction::OnGetFileInfo, this)); 100 return true; 101} 102 103void GetDriveEntryPropertiesFunction::OnGetFileInfo( 104 drive::FileError error, 105 scoped_ptr<drive::ResourceEntry> entry) { 106 DCHECK(properties_); 107 108 if (error != drive::FILE_ERROR_OK) { 109 CompleteGetFileProperties(error); 110 return; 111 } 112 DCHECK(entry); 113 114 FillDriveEntryPropertiesValue(*entry, properties_.get()); 115 116 drive::DriveIntegrationService* integration_service = 117 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 118 // |integration_service| is NULL if Drive is disabled. 119 if (!integration_service) { 120 CompleteGetFileProperties(drive::FILE_ERROR_FAILED); 121 return; 122 } 123 124 // The properties meaningful for directories are already filled in 125 // FillDriveEntryPropertiesValue(). 126 if (entry.get() && !entry->has_file_specific_info()) { 127 CompleteGetFileProperties(error); 128 return; 129 } 130 131 const drive::FileSpecificInfo& file_specific_info = 132 entry->file_specific_info(); 133 134 // Get drive WebApps that can accept this file. 135 ScopedVector<drive::DriveAppInfo> drive_apps; 136 integration_service->drive_app_registry()->GetAppsForFile( 137 file_path_, file_specific_info.content_mime_type(), &drive_apps); 138 if (!drive_apps.empty()) { 139 std::string default_task_id = file_tasks::GetDefaultTaskIdFromPrefs( 140 profile_, 141 file_specific_info.content_mime_type(), 142 file_path_.Extension()); 143 file_tasks::TaskDescriptor default_task; 144 file_tasks::ParseTaskID(default_task_id, &default_task); 145 DCHECK(default_task_id.empty() || !default_task.app_id.empty()); 146 147 ListValue* apps = new ListValue(); 148 properties_->Set("driveApps", apps); 149 for (ScopedVector<drive::DriveAppInfo>::const_iterator it = 150 drive_apps.begin(); 151 it != drive_apps.end(); ++it) { 152 const drive::DriveAppInfo* app_info = *it; 153 DictionaryValue* app = new DictionaryValue(); 154 app->SetString("appId", app_info->app_id); 155 app->SetString("appName", app_info->app_name); 156 GURL app_icon = util::FindPreferredIcon(app_info->app_icons, 157 util::kPreferredIconSize); 158 if (!app_icon.is_empty()) 159 app->SetString("appIcon", app_icon.spec()); 160 GURL doc_icon = util::FindPreferredIcon(app_info->document_icons, 161 util::kPreferredIconSize); 162 if (!doc_icon.is_empty()) 163 app->SetString("docIcon", doc_icon.spec()); 164 app->SetString("objectType", app_info->object_type); 165 app->SetBoolean("isPrimary", 166 default_task.app_id == app_info->app_id); 167 apps->Append(app); 168 } 169 } 170 171 integration_service->file_system()->GetCacheEntryByResourceId( 172 entry->resource_id(), 173 base::Bind(&GetDriveEntryPropertiesFunction::CacheStateReceived, this)); 174} 175 176void GetDriveEntryPropertiesFunction::CacheStateReceived( 177 bool /* success */, 178 const drive::FileCacheEntry& cache_entry) { 179 // In case of an error (i.e. success is false), cache_entry.is_*() all 180 // returns false. 181 properties_->SetBoolean("isPinned", cache_entry.is_pinned()); 182 properties_->SetBoolean("isPresent", cache_entry.is_present()); 183 properties_->SetBoolean("isDirty", cache_entry.is_dirty()); 184 185 CompleteGetFileProperties(drive::FILE_ERROR_OK); 186} 187 188void GetDriveEntryPropertiesFunction::CompleteGetFileProperties( 189 drive::FileError error) { 190 if (error != drive::FILE_ERROR_OK) 191 properties_->SetInteger("errorCode", error); 192 SetResult(properties_.release()); 193 SendResponse(true); 194} 195 196PinDriveFileFunction::PinDriveFileFunction() { 197} 198 199PinDriveFileFunction::~PinDriveFileFunction() { 200} 201 202bool PinDriveFileFunction::RunImpl() { 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 204 std::string url; 205 bool set_pin = false; 206 if (args_->GetSize() != 2 || 207 !args_->GetString(0, &url) || 208 !args_->GetBoolean(1, &set_pin)) 209 return false; 210 211 drive::DriveIntegrationService* integration_service = 212 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 213 drive::FileSystemInterface* file_system = 214 integration_service ? integration_service->file_system() : NULL; 215 if (!file_system) // |file_system| is NULL if Drive is disabled. 216 return false; 217 218 base::FilePath drive_path = 219 drive::util::ExtractDrivePath( 220 util::GetLocalPathFromURL(render_view_host(), profile(), GURL(url))); 221 if (set_pin) { 222 file_system->Pin(drive_path, 223 base::Bind(&PinDriveFileFunction::OnPinStateSet, this)); 224 } else { 225 file_system->Unpin(drive_path, 226 base::Bind(&PinDriveFileFunction::OnPinStateSet, this)); 227 } 228 return true; 229} 230 231void PinDriveFileFunction::OnPinStateSet(drive::FileError error) { 232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 233 234 if (error == drive::FILE_ERROR_OK) { 235 SendResponse(true); 236 } else { 237 error_ = drive::FileErrorToString(error); 238 SendResponse(false); 239 } 240} 241 242GetDriveFilesFunction::GetDriveFilesFunction() 243 : local_paths_(NULL) { 244} 245 246GetDriveFilesFunction::~GetDriveFilesFunction() { 247} 248 249bool GetDriveFilesFunction::RunImpl() { 250 ListValue* file_urls_as_strings = NULL; 251 if (!args_->GetList(0, &file_urls_as_strings)) 252 return false; 253 254 // Convert the list of strings to a list of GURLs. 255 for (size_t i = 0; i < file_urls_as_strings->GetSize(); ++i) { 256 std::string file_url_as_string; 257 if (!file_urls_as_strings->GetString(i, &file_url_as_string)) 258 return false; 259 const base::FilePath path = util::GetLocalPathFromURL( 260 render_view_host(), profile(), GURL(file_url_as_string)); 261 DCHECK(drive::util::IsUnderDriveMountPoint(path)); 262 base::FilePath drive_path = drive::util::ExtractDrivePath(path); 263 remaining_drive_paths_.push(drive_path); 264 } 265 266 local_paths_ = new ListValue; 267 GetFileOrSendResponse(); 268 return true; 269} 270 271void GetDriveFilesFunction::GetFileOrSendResponse() { 272 // Send the response if all files are obtained. 273 if (remaining_drive_paths_.empty()) { 274 SetResult(local_paths_); 275 SendResponse(true); 276 return; 277 } 278 279 // Get the file on the top of the queue. 280 base::FilePath drive_path = remaining_drive_paths_.front(); 281 282 drive::DriveIntegrationService* integration_service = 283 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 284 // |integration_service| is NULL if Drive is disabled. 285 if (!integration_service) { 286 OnFileReady(drive::FILE_ERROR_FAILED, drive_path, 287 scoped_ptr<drive::ResourceEntry>()); 288 return; 289 } 290 291 integration_service->file_system()->GetFileByPath( 292 drive_path, 293 base::Bind(&GetDriveFilesFunction::OnFileReady, this)); 294} 295 296 297void GetDriveFilesFunction::OnFileReady( 298 drive::FileError error, 299 const base::FilePath& local_path, 300 scoped_ptr<drive::ResourceEntry> entry) { 301 base::FilePath drive_path = remaining_drive_paths_.front(); 302 303 if (error == drive::FILE_ERROR_OK) { 304 local_paths_->Append(new base::StringValue(local_path.value())); 305 DVLOG(1) << "Got " << drive_path.value() << " as " << local_path.value(); 306 307 // TODO(benchan): If the file is a hosted document, a temporary JSON file 308 // is created to represent the document. The JSON file is not cached and 309 // should be deleted after use. We need to somehow communicate with 310 // file_manager.js to manage the lifetime of the temporary file. 311 // See crosbug.com/28058. 312 } else { 313 local_paths_->Append(new base::StringValue("")); 314 DVLOG(1) << "Failed to get " << drive_path.value() 315 << " with error code: " << error; 316 } 317 318 remaining_drive_paths_.pop(); 319 320 // Start getting the next file. 321 GetFileOrSendResponse(); 322} 323 324CancelFileTransfersFunction::CancelFileTransfersFunction() { 325} 326 327CancelFileTransfersFunction::~CancelFileTransfersFunction() { 328} 329 330bool CancelFileTransfersFunction::RunImpl() { 331 ListValue* url_list = NULL; 332 if (!args_->GetList(0, &url_list)) 333 return false; 334 335 drive::DriveIntegrationService* integration_service = 336 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 337 // |integration_service| is NULL if Drive is disabled. 338 if (!integration_service) 339 return false; 340 341 // Create the mapping from file path to job ID. 342 drive::JobListInterface* job_list = integration_service->job_list(); 343 DCHECK(job_list); 344 std::vector<drive::JobInfo> jobs = job_list->GetJobInfoList(); 345 346 typedef std::map<base::FilePath, std::vector<drive::JobID> > PathToIdMap; 347 PathToIdMap path_to_id_map; 348 for (size_t i = 0; i < jobs.size(); ++i) { 349 if (drive::IsActiveFileTransferJobInfo(jobs[i])) 350 path_to_id_map[jobs[i].file_path].push_back(jobs[i].job_id); 351 } 352 353 // Cancel by Job ID. 354 scoped_ptr<ListValue> responses(new ListValue()); 355 for (size_t i = 0; i < url_list->GetSize(); ++i) { 356 std::string url_as_string; 357 url_list->GetString(i, &url_as_string); 358 359 base::FilePath file_path = util::GetLocalPathFromURL( 360 render_view_host(), profile(), GURL(url_as_string)); 361 if (file_path.empty()) 362 continue; 363 364 DCHECK(drive::util::IsUnderDriveMountPoint(file_path)); 365 file_path = drive::util::ExtractDrivePath(file_path); 366 scoped_ptr<DictionaryValue> result(new DictionaryValue()); 367 368 // Cancel all the jobs for the file. 369 PathToIdMap::iterator it = path_to_id_map.find(file_path); 370 if (it != path_to_id_map.end()) { 371 for (size_t i = 0; i < it->second.size(); ++i) 372 job_list->CancelJob(it->second[i]); 373 } 374 result->SetBoolean("canceled", it != path_to_id_map.end()); 375 // TODO(kinaba): simplify cancelFileTransfer() to take single URL each time, 376 // and eliminate this field; it is just returning a copy of the argument. 377 result->SetString("fileUrl", url_as_string); 378 responses->Append(result.release()); 379 } 380 SetResult(responses.release()); 381 SendResponse(true); 382 return true; 383} 384 385SearchDriveFunction::SearchDriveFunction() { 386} 387 388SearchDriveFunction::~SearchDriveFunction() { 389} 390 391bool SearchDriveFunction::RunImpl() { 392 DictionaryValue* search_params; 393 if (!args_->GetDictionary(0, &search_params)) 394 return false; 395 396 std::string query; 397 if (!search_params->GetString("query", &query)) 398 return false; 399 400 std::string next_feed; 401 if (!search_params->GetString("nextFeed", &next_feed)) 402 return false; 403 404 drive::DriveIntegrationService* integration_service = 405 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 406 // |integration_service| is NULL if Drive is disabled. 407 if (!integration_service || !integration_service->file_system()) 408 return false; 409 410 integration_service->file_system()->Search( 411 query, GURL(next_feed), 412 base::Bind(&SearchDriveFunction::OnSearch, this)); 413 return true; 414} 415 416void SearchDriveFunction::OnSearch( 417 drive::FileError error, 418 const GURL& next_feed, 419 scoped_ptr<std::vector<drive::SearchResultInfo> > results) { 420 if (error != drive::FILE_ERROR_OK) { 421 SendResponse(false); 422 return; 423 } 424 425 DCHECK(results.get()); 426 427 base::ListValue* entries = new ListValue(); 428 429 // Convert Drive files to something File API stack can understand. 430 GURL origin_url = source_url_.GetOrigin(); 431 fileapi::FileSystemType file_system_type = fileapi::kFileSystemTypeExternal; 432 GURL file_system_root_url = 433 fileapi::GetFileSystemRootURI(origin_url, file_system_type); 434 std::string file_system_name = 435 fileapi::GetFileSystemName(origin_url, file_system_type); 436 for (size_t i = 0; i < results->size(); ++i) { 437 DictionaryValue* entry = new DictionaryValue(); 438 entry->SetString("fileSystemName", file_system_name); 439 entry->SetString("fileSystemRoot", file_system_root_url.spec()); 440 entry->SetString("fileFullPath", "/" + results->at(i).path.value()); 441 entry->SetBoolean("fileIsDirectory", 442 results->at(i).entry.file_info().is_directory()); 443 entries->Append(entry); 444 } 445 446 base::DictionaryValue* result = new DictionaryValue(); 447 result->Set("entries", entries); 448 result->SetString("nextFeed", next_feed.spec()); 449 450 SetResult(result); 451 SendResponse(true); 452} 453 454SearchDriveMetadataFunction::SearchDriveMetadataFunction() { 455} 456 457SearchDriveMetadataFunction::~SearchDriveMetadataFunction() { 458} 459 460bool SearchDriveMetadataFunction::RunImpl() { 461 DictionaryValue* search_params; 462 if (!args_->GetDictionary(0, &search_params)) 463 return false; 464 465 std::string query; 466 if (!search_params->GetString("query", &query)) 467 return false; 468 469 std::string types; 470 if (!search_params->GetString("types", &types)) 471 return false; 472 473 int max_results = 0; 474 if (!search_params->GetInteger("maxResults", &max_results)) 475 return false; 476 477 drive::util::Log(logging::LOG_INFO, 478 "%s[%d] called. (types: '%s', maxResults: '%d')", 479 name().c_str(), 480 request_id(), 481 types.c_str(), 482 max_results); 483 set_log_on_completion(true); 484 485 drive::DriveIntegrationService* integration_service = 486 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 487 // |integration_service| is NULL if Drive is disabled. 488 if (!integration_service || !integration_service->file_system()) 489 return false; 490 491 int options = drive::SEARCH_METADATA_ALL; 492 // TODO(hirono): Switch to the JSON scheme compiler. http://crbug.com/241693 493 if (types == "EXCLUDE_DIRECTORIES") 494 options = drive::SEARCH_METADATA_EXCLUDE_DIRECTORIES; 495 else if (types == "SHARED_WITH_ME") 496 options = drive::SEARCH_METADATA_SHARED_WITH_ME; 497 else if (types == "OFFLINE") 498 options = drive::SEARCH_METADATA_OFFLINE; 499 else 500 DCHECK_EQ("ALL", types); 501 502 integration_service->file_system()->SearchMetadata( 503 query, 504 options, 505 max_results, 506 base::Bind(&SearchDriveMetadataFunction::OnSearchMetadata, this)); 507 return true; 508} 509 510void SearchDriveMetadataFunction::OnSearchMetadata( 511 drive::FileError error, 512 scoped_ptr<drive::MetadataSearchResultVector> results) { 513 if (error != drive::FILE_ERROR_OK) { 514 SendResponse(false); 515 return; 516 } 517 518 DCHECK(results.get()); 519 520 base::ListValue* results_list = new ListValue(); 521 522 // Convert Drive files to something File API stack can understand. See 523 // file_browser_handler_custom_bindings.cc and 524 // file_browser_private_custom_bindings.js for how this is magically 525 // converted to a FileEntry. 526 GURL origin_url = source_url_.GetOrigin(); 527 fileapi::FileSystemType file_system_type = fileapi::kFileSystemTypeExternal; 528 GURL file_system_root_url = 529 fileapi::GetFileSystemRootURI(origin_url, file_system_type); 530 std::string file_system_name = 531 fileapi::GetFileSystemName(origin_url, file_system_type); 532 for (size_t i = 0; i < results->size(); ++i) { 533 DictionaryValue* result_dict = new DictionaryValue(); 534 535 // FileEntry fields. 536 DictionaryValue* entry = new DictionaryValue(); 537 entry->SetString("fileSystemName", file_system_name); 538 entry->SetString("fileSystemRoot", file_system_root_url.spec()); 539 entry->SetString("fileFullPath", "/" + results->at(i).path.value()); 540 entry->SetBoolean("fileIsDirectory", 541 results->at(i).entry.file_info().is_directory()); 542 543 result_dict->Set("entry", entry); 544 result_dict->SetString("highlightedBaseName", 545 results->at(i).highlighted_base_name); 546 results_list->Append(result_dict); 547 } 548 549 SetResult(results_list); 550 SendResponse(true); 551} 552 553ClearDriveCacheFunction::ClearDriveCacheFunction() { 554} 555 556ClearDriveCacheFunction::~ClearDriveCacheFunction() { 557} 558 559bool ClearDriveCacheFunction::RunImpl() { 560 drive::DriveIntegrationService* integration_service = 561 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 562 // |integration_service| is NULL if Drive is disabled. 563 if (!integration_service || !integration_service->file_system()) 564 return false; 565 566 // TODO(yoshiki): Receive a callback from JS-side and pass it to 567 // ClearCacheAndRemountFileSystem(). http://crbug.com/140511 568 integration_service->ClearCacheAndRemountFileSystem( 569 base::Bind(&DoNothingWithBool)); 570 571 SendResponse(true); 572 return true; 573} 574 575GetDriveConnectionStateFunction::GetDriveConnectionStateFunction() { 576} 577 578GetDriveConnectionStateFunction::~GetDriveConnectionStateFunction() { 579} 580 581bool GetDriveConnectionStateFunction::RunImpl() { 582 scoped_ptr<DictionaryValue> value(new DictionaryValue()); 583 scoped_ptr<ListValue> reasons(new ListValue()); 584 585 std::string type_string; 586 drive::DriveIntegrationService* integration_service = 587 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 588 589 bool ready = integration_service && 590 integration_service->drive_service()->CanSendRequest(); 591 bool is_connection_cellular = 592 net::NetworkChangeNotifier::IsConnectionCellular( 593 net::NetworkChangeNotifier::GetConnectionType()); 594 595 if (net::NetworkChangeNotifier::IsOffline() || !ready) { 596 type_string = kDriveConnectionTypeOffline; 597 if (net::NetworkChangeNotifier::IsOffline()) 598 reasons->AppendString(kDriveConnectionReasonNoNetwork); 599 if (!ready) 600 reasons->AppendString(kDriveConnectionReasonNotReady); 601 if (!integration_service) 602 reasons->AppendString(kDriveConnectionReasonNoService); 603 } else if ( 604 is_connection_cellular && 605 profile_->GetPrefs()->GetBoolean(prefs::kDisableDriveOverCellular)) { 606 type_string = kDriveConnectionTypeMetered; 607 } else { 608 type_string = kDriveConnectionTypeOnline; 609 } 610 611 value->SetString("type", type_string); 612 value->Set("reasons", reasons.release()); 613 SetResult(value.release()); 614 615 drive::util::Log(logging::LOG_INFO, "%s succeeded.", name().c_str()); 616 return true; 617} 618 619RequestAccessTokenFunction::RequestAccessTokenFunction() { 620} 621 622RequestAccessTokenFunction::~RequestAccessTokenFunction() { 623} 624 625bool RequestAccessTokenFunction::RunImpl() { 626 drive::DriveIntegrationService* integration_service = 627 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 628 bool refresh; 629 args_->GetBoolean(0, &refresh); 630 631 if (!integration_service) { 632 SetResult(new base::StringValue("")); 633 SendResponse(true); 634 return true; 635 } 636 637 // If refreshing is requested, then clear the token to refetch it. 638 if (refresh) 639 integration_service->drive_service()->ClearAccessToken(); 640 641 // Retrieve the cached auth token (if available), otherwise the AuthService 642 // instance will try to refetch it. 643 integration_service->drive_service()->RequestAccessToken( 644 base::Bind(&RequestAccessTokenFunction::OnAccessTokenFetched, this)); 645 return true; 646} 647 648void RequestAccessTokenFunction::OnAccessTokenFetched( 649 google_apis::GDataErrorCode code, const std::string& access_token) { 650 SetResult(new base::StringValue(access_token)); 651 SendResponse(true); 652} 653 654GetShareUrlFunction::GetShareUrlFunction() { 655} 656 657GetShareUrlFunction::~GetShareUrlFunction() { 658} 659 660bool GetShareUrlFunction::RunImpl() { 661 std::string file_url; 662 if (!args_->GetString(0, &file_url)) 663 return false; 664 665 const base::FilePath path = util::GetLocalPathFromURL( 666 render_view_host(), profile(), GURL(file_url)); 667 DCHECK(drive::util::IsUnderDriveMountPoint(path)); 668 669 base::FilePath drive_path = drive::util::ExtractDrivePath(path); 670 671 drive::DriveIntegrationService* integration_service = 672 drive::DriveIntegrationServiceFactory::GetForProfile(profile_); 673 // |integration_service| is NULL if Drive is disabled. 674 if (!integration_service) 675 return false; 676 677 integration_service->file_system()->GetShareUrl( 678 drive_path, 679 util::GetFileManagerBaseUrl(), // embed origin 680 base::Bind(&GetShareUrlFunction::OnGetShareUrl, this)); 681 return true; 682} 683 684 685void GetShareUrlFunction::OnGetShareUrl(drive::FileError error, 686 const GURL& share_url) { 687 if (error != drive::FILE_ERROR_OK) { 688 error_ = "Share Url for this item is not available."; 689 SendResponse(false); 690 return; 691 } 692 693 SetResult(new base::StringValue(share_url.spec())); 694 SendResponse(true); 695} 696 697} // namespace file_manager 698