1// Copyright (c) 2012 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/drive/file_task_executor.h" 6 7#include <string> 8#include <vector> 9 10#include "chrome/browser/chromeos/drive/drive.pb.h" 11#include "chrome/browser/chromeos/drive/drive_integration_service.h" 12#include "chrome/browser/chromeos/drive/file_system_interface.h" 13#include "chrome/browser/drive/drive_service_interface.h" 14#include "chrome/browser/profiles/profile_manager.h" 15#include "chrome/browser/ui/browser.h" 16#include "chrome/browser/ui/browser_tabstrip.h" 17#include "chrome/browser/ui/browser_window.h" 18#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 19#include "content/public/browser/browser_thread.h" 20#include "webkit/browser/fileapi/file_system_url.h" 21 22using fileapi::FileSystemURL; 23 24namespace drive { 25 26FileTaskExecutor::FileTaskExecutor(Profile* profile, 27 const std::string& app_id) 28 : profile_(profile), 29 app_id_(app_id), 30 current_index_(0), 31 weak_ptr_factory_(this) { 32} 33 34FileTaskExecutor::~FileTaskExecutor() { 35} 36 37void FileTaskExecutor::Execute( 38 const std::vector<FileSystemURL>& file_urls, 39 const file_manager::file_tasks::FileTaskFinishedCallback& done) { 40 done_ = done; 41 42 std::vector<base::FilePath> paths; 43 for (size_t i = 0; i < file_urls.size(); ++i) { 44 base::FilePath path = util::ExtractDrivePathFromFileSystemUrl(file_urls[i]); 45 if (path.empty()) { 46 Done(false); 47 return; 48 } 49 paths.push_back(path); 50 } 51 52 FileSystemInterface* file_system = util::GetFileSystemByProfile(profile_); 53 if (!file_system) { 54 Done(false); 55 return; 56 } 57 58 // Reset the index, so we know when we're done. 59 DCHECK_EQ(current_index_, 0); 60 current_index_ = paths.size(); 61 62 for (size_t i = 0; i < paths.size(); ++i) { 63 file_system->GetResourceEntry( 64 paths[i], 65 base::Bind(&FileTaskExecutor::OnFileEntryFetched, 66 weak_ptr_factory_.GetWeakPtr())); 67 } 68} 69 70void FileTaskExecutor::OnFileEntryFetched(FileError error, 71 scoped_ptr<ResourceEntry> entry) { 72 // Here, we are only interested in files. 73 if (entry.get() && !entry->has_file_specific_info()) 74 error = FILE_ERROR_NOT_FOUND; 75 76 DriveServiceInterface* drive_service = 77 util::GetDriveServiceByProfile(profile_); 78 79 if (!drive_service || error != FILE_ERROR_OK) { 80 Done(false); 81 return; 82 } 83 84 // Send off a request for the drive service to authorize the apps for the 85 // current document entry for this document so we can get the 86 // open-with-<app_id> urls from the document entry. 87 drive_service->AuthorizeApp(entry->resource_id(), 88 app_id_, 89 base::Bind(&FileTaskExecutor::OnAppAuthorized, 90 weak_ptr_factory_.GetWeakPtr(), 91 entry->resource_id())); 92} 93 94void FileTaskExecutor::OnAppAuthorized(const std::string& resource_id, 95 google_apis::GDataErrorCode error, 96 const GURL& open_link) { 97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 98 99 DriveIntegrationService* service = 100 DriveIntegrationServiceFactory::FindForProfile(profile_); 101 if (!service || !service->IsMounted() || 102 error != google_apis::HTTP_SUCCESS || open_link.is_empty()) { 103 Done(false); 104 return; 105 } 106 107 { 108 chrome::ScopedTabbedBrowserDisplayer displayer( 109 profile_, chrome::HOST_DESKTOP_TYPE_ASH); 110 chrome::AddSelectedTabWithURL(displayer.browser(), open_link, 111 content::PAGE_TRANSITION_LINK); 112 } 113 114 // We're done with this file. If this is the last one, then we're done. 115 current_index_--; 116 DCHECK_GE(current_index_, 0); 117 if (current_index_ == 0) 118 Done(true); 119} 120 121void FileTaskExecutor::Done(bool success) { 122 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 123 if (!done_.is_null()) 124 done_.Run(success); 125 delete this; 126} 127 128} // namespace drive 129