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.
5 #include "chrome/browser/chromeos/drive/file_task_executor.h"
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/ash/multi_user/multi_user_util.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_tabstrip.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
20 #include "chrome/common/extensions/api/file_manager_private.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "storage/browser/fileapi/file_system_url.h"
24 using storage::FileSystemURL
;
30 class FileTaskExecutorDelegateImpl
: public FileTaskExecutorDelegate
{
32 explicit FileTaskExecutorDelegateImpl(Profile
* profile
) : profile_(profile
) {
35 FileSystemInterface
* GetFileSystem() override
{
36 return util::GetFileSystemByProfile(profile_
);
39 DriveServiceInterface
* GetDriveService() override
{
40 return util::GetDriveServiceByProfile(profile_
);
43 void OpenBrowserWindow(const GURL
& open_link
) override
{
44 chrome::ScopedTabbedBrowserDisplayer
displayer(
45 profile_
, chrome::HOST_DESKTOP_TYPE_ASH
);
46 chrome::AddSelectedTabWithURL(displayer
.browser(), open_link
,
47 ui::PAGE_TRANSITION_LINK
);
48 // Since the ScopedTabbedBrowserDisplayer does not guarantee that the
49 // browser will be shown on the active desktop, we ensure the visibility.
50 multi_user_util::MoveWindowToCurrentDesktop(
51 displayer
.browser()->window()->GetNativeWindow());
55 Profile
* const profile_
;
60 FileTaskExecutor::FileTaskExecutor(Profile
* profile
, const std::string
& app_id
)
61 : delegate_(new FileTaskExecutorDelegateImpl(profile
)),
64 weak_ptr_factory_(this) {
67 FileTaskExecutor::FileTaskExecutor(
68 scoped_ptr
<FileTaskExecutorDelegate
> delegate
,
69 const std::string
& app_id
)
70 : delegate_(delegate
.Pass()),
73 weak_ptr_factory_(this) {
76 FileTaskExecutor::~FileTaskExecutor() {
79 void FileTaskExecutor::Execute(
80 const std::vector
<FileSystemURL
>& file_urls
,
81 const file_manager::file_tasks::FileTaskFinishedCallback
& done
) {
82 DCHECK(!file_urls
.empty());
86 std::vector
<base::FilePath
> paths
;
87 for (size_t i
= 0; i
< file_urls
.size(); ++i
) {
88 base::FilePath path
= util::ExtractDrivePathFromFileSystemUrl(file_urls
[i
]);
93 paths
.push_back(path
);
96 FileSystemInterface
* const file_system
= delegate_
->GetFileSystem();
102 // Reset the index, so we know when we're done.
103 DCHECK_EQ(current_index_
, 0);
104 current_index_
= paths
.size();
106 for (size_t i
= 0; i
< paths
.size(); ++i
) {
107 file_system
->GetResourceEntry(
109 base::Bind(&FileTaskExecutor::OnFileEntryFetched
,
110 weak_ptr_factory_
.GetWeakPtr()));
114 void FileTaskExecutor::OnFileEntryFetched(FileError error
,
115 scoped_ptr
<ResourceEntry
> entry
) {
116 // Here, we are only interested in files.
117 if (entry
.get() && !entry
->has_file_specific_info())
118 error
= FILE_ERROR_NOT_FOUND
;
120 DriveServiceInterface
* const drive_service
= delegate_
->GetDriveService();
121 if (!drive_service
|| error
!= FILE_ERROR_OK
) {
126 // Send off a request for the drive service to authorize the apps for the
127 // current document entry for this document so we can get the
128 // open-with-<app_id> urls from the document entry.
129 drive_service
->AuthorizeApp(entry
->resource_id(),
131 base::Bind(&FileTaskExecutor::OnAppAuthorized
,
132 weak_ptr_factory_
.GetWeakPtr(),
133 entry
->resource_id()));
136 void FileTaskExecutor::OnAppAuthorized(const std::string
& resource_id
,
137 google_apis::DriveApiErrorCode error
,
138 const GURL
& open_link
) {
139 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
141 if (error
!= google_apis::HTTP_SUCCESS
|| open_link
.is_empty()) {
146 delegate_
->OpenBrowserWindow(open_link
);
148 // We're done with this file. If this is the last one, then we're done.
150 DCHECK_GE(current_index_
, 0);
151 if (current_index_
== 0)
155 void FileTaskExecutor::Done(bool success
) {
156 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
157 if (!done_
.is_null())
159 ? extensions::api::file_manager_private::TASK_RESULT_OPENED
160 : extensions::api::file_manager_private::TASK_RESULT_FAILED
);