file_task_executor.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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 "base/json/json_writer.h" 11#include "base/string_util.h" 12#include "chrome/browser/chromeos/drive/drive.pb.h" 13#include "chrome/browser/chromeos/drive/drive_system_service.h" 14#include "chrome/browser/chromeos/drive/file_system_interface.h" 15#include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h" 16#include "chrome/browser/google_apis/drive_service_interface.h" 17#include "chrome/browser/google_apis/gdata_wapi_parser.h" 18#include "chrome/browser/profiles/profile.h" 19#include "chrome/browser/profiles/profile_manager.h" 20#include "chrome/browser/ui/browser.h" 21#include "chrome/browser/ui/browser_finder.h" 22#include "chrome/browser/ui/browser_tabstrip.h" 23#include "chrome/browser/ui/browser_window.h" 24#include "content/public/browser/browser_thread.h" 25#include "webkit/fileapi/file_system_types.h" 26#include "webkit/fileapi/file_system_url.h" 27#include "webkit/fileapi/file_system_util.h" 28 29using file_handler_util::FileTaskExecutor; 30using fileapi::FileSystemURL; 31 32namespace drive { 33 34FileTaskExecutor::FileTaskExecutor(Profile* profile, 35 const std::string& app_id, 36 const std::string& action_id) 37 : file_handler_util::FileTaskExecutor(profile, GURL(), "", app_id), 38 action_id_(action_id), 39 current_index_(0) { 40 DCHECK("open-with" == action_id_); 41} 42 43FileTaskExecutor::~FileTaskExecutor() { 44} 45 46bool FileTaskExecutor::ExecuteAndNotify( 47 const std::vector<FileSystemURL>& file_urls, 48 const file_handler_util::FileTaskFinishedCallback& done) { 49 std::vector<base::FilePath> raw_paths; 50 for (std::vector<FileSystemURL>::const_iterator url = file_urls.begin(); 51 url != file_urls.end(); ++url) { 52 base::FilePath path = util::ExtractDrivePathFromFileSystemUrl(*url); 53 if (path.empty()) 54 return false; 55 raw_paths.push_back(path); 56 } 57 58 DriveSystemService* system_service = 59 DriveSystemServiceFactory::GetForProfile(profile()); 60 DCHECK(current_index_ == 0); 61 if (!system_service || !system_service->file_system()) 62 return false; 63 FileSystemInterface* file_system = system_service->file_system(); 64 65 // Reset the index, so we know when we're done. 66 current_index_ = raw_paths.size(); 67 68 for (std::vector<base::FilePath>::const_iterator iter = raw_paths.begin(); 69 iter != raw_paths.end(); ++iter) { 70 file_system->GetResourceEntryByPath( 71 *iter, 72 base::Bind(&FileTaskExecutor::OnFileEntryFetched, this)); 73 } 74 return true; 75} 76 77void FileTaskExecutor::OnFileEntryFetched( 78 FileError error, 79 scoped_ptr<ResourceEntry> entry) { 80 // If we aborted, then this will be zero. 81 if (!current_index_) 82 return; 83 84 DriveSystemService* system_service = 85 DriveSystemServiceFactory::GetForProfile(profile()); 86 87 // Here, we are only interested in files. 88 if (entry.get() && !entry->has_file_specific_info()) 89 error = FILE_ERROR_NOT_FOUND; 90 91 if (!system_service || error != FILE_ERROR_OK) { 92 Done(false); 93 return; 94 } 95 96 google_apis::DriveServiceInterface* drive_service = 97 system_service->drive_service(); 98 99 // Send off a request for the drive service to authorize the apps for the 100 // current document entry for this document so we can get the 101 // open-with-<app_id> urls from the document entry. 102 drive_service->AuthorizeApp( 103 entry->resource_id(), 104 extension_id(), // really app_id 105 base::Bind(&FileTaskExecutor::OnAppAuthorized, 106 this, 107 entry->resource_id())); 108} 109 110void FileTaskExecutor::OnAppAuthorized( 111 const std::string& resource_id, 112 google_apis::GDataErrorCode error, 113 const GURL& open_link) { 114 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 115 116 // If we aborted, then this will be zero. 117 if (!current_index_) 118 return; 119 120 DriveSystemService* system_service = 121 DriveSystemServiceFactory::GetForProfile(profile()); 122 123 if (!system_service || error != google_apis::HTTP_SUCCESS) { 124 Done(false); 125 return; 126 } 127 128 if (open_link.is_empty()) { 129 Done(false); 130 return; 131 } 132 133 Browser* browser = GetBrowser(); 134 chrome::AddSelectedTabWithURL(browser, open_link, 135 content::PAGE_TRANSITION_LINK); 136 // If the current browser is not tabbed then the new tab will be created 137 // in a different browser. Make sure it is visible. 138 browser->window()->Show(); 139 140 // We're done with this file. If this is the last one, then we're done. 141 current_index_--; 142 DCHECK(current_index_ >= 0); 143 if (current_index_ == 0) 144 Done(true); 145} 146 147void FileTaskExecutor::Done(bool success) { 148 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 149 current_index_ = 0; 150 if (!done_.is_null()) 151 done_.Run(success); 152 done_.Reset(); 153} 154 155} // namespace drive 156