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_integration_service.h"
11 #include "chrome/browser/chromeos/drive/file_system_interface.h"
12 #include "chrome/browser/chromeos/drive/file_system_util.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/ui/ash/multi_user/multi_user_util.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 "chrome/common/extensions/api/file_manager_private.h"
20 #include "components/drive/drive.pb.h"
21 #include "components/drive/service/drive_service_interface.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "storage/browser/fileapi/file_system_url.h"
25 using storage::FileSystemURL
;
31 class FileTaskExecutorDelegateImpl
: public FileTaskExecutorDelegate
{
33 explicit FileTaskExecutorDelegateImpl(Profile
* profile
) : profile_(profile
) {
36 FileSystemInterface
* GetFileSystem() override
{
37 return util::GetFileSystemByProfile(profile_
);
40 DriveServiceInterface
* GetDriveService() override
{
41 return util::GetDriveServiceByProfile(profile_
);
44 void OpenBrowserWindow(const GURL
& open_link
) override
{
45 chrome::ScopedTabbedBrowserDisplayer
displayer(
46 profile_
, chrome::HOST_DESKTOP_TYPE_ASH
);
47 chrome::AddSelectedTabWithURL(displayer
.browser(), open_link
,
48 ui::PAGE_TRANSITION_LINK
);
49 // Since the ScopedTabbedBrowserDisplayer does not guarantee that the
50 // browser will be shown on the active desktop, we ensure the visibility.
51 multi_user_util::MoveWindowToCurrentDesktop(
52 displayer
.browser()->window()->GetNativeWindow());
56 Profile
* const profile_
;
61 FileTaskExecutor::FileTaskExecutor(Profile
* profile
, const std::string
& app_id
)
62 : delegate_(new FileTaskExecutorDelegateImpl(profile
)),
65 weak_ptr_factory_(this) {
68 FileTaskExecutor::FileTaskExecutor(
69 scoped_ptr
<FileTaskExecutorDelegate
> delegate
,
70 const std::string
& app_id
)
71 : delegate_(delegate
.Pass()),
74 weak_ptr_factory_(this) {
77 FileTaskExecutor::~FileTaskExecutor() {
80 void FileTaskExecutor::Execute(
81 const std::vector
<FileSystemURL
>& file_urls
,
82 const file_manager::file_tasks::FileTaskFinishedCallback
& done
) {
83 DCHECK(!file_urls
.empty());
87 std::vector
<base::FilePath
> paths
;
88 for (size_t i
= 0; i
< file_urls
.size(); ++i
) {
89 base::FilePath path
= util::ExtractDrivePathFromFileSystemUrl(file_urls
[i
]);
94 paths
.push_back(path
);
97 FileSystemInterface
* const file_system
= delegate_
->GetFileSystem();
103 // Reset the index, so we know when we're done.
104 DCHECK_EQ(current_index_
, 0);
105 current_index_
= paths
.size();
107 for (size_t i
= 0; i
< paths
.size(); ++i
) {
108 file_system
->GetResourceEntry(
110 base::Bind(&FileTaskExecutor::OnFileEntryFetched
,
111 weak_ptr_factory_
.GetWeakPtr()));
115 void FileTaskExecutor::OnFileEntryFetched(FileError error
,
116 scoped_ptr
<ResourceEntry
> entry
) {
117 // Here, we are only interested in files.
118 if (entry
.get() && !entry
->has_file_specific_info())
119 error
= FILE_ERROR_NOT_FOUND
;
121 DriveServiceInterface
* const drive_service
= delegate_
->GetDriveService();
122 if (!drive_service
|| error
!= FILE_ERROR_OK
) {
127 // Send off a request for the drive service to authorize the apps for the
128 // current document entry for this document so we can get the
129 // open-with-<app_id> urls from the document entry.
130 drive_service
->AuthorizeApp(entry
->resource_id(),
132 base::Bind(&FileTaskExecutor::OnAppAuthorized
,
133 weak_ptr_factory_
.GetWeakPtr(),
134 entry
->resource_id()));
137 void FileTaskExecutor::OnAppAuthorized(const std::string
& resource_id
,
138 google_apis::DriveApiErrorCode error
,
139 const GURL
& open_link
) {
140 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
142 if (error
!= google_apis::HTTP_SUCCESS
|| open_link
.is_empty()) {
147 delegate_
->OpenBrowserWindow(open_link
);
149 // We're done with this file. If this is the last one, then we're done.
151 DCHECK_GE(current_index_
, 0);
152 if (current_index_
== 0)
156 void FileTaskExecutor::Done(bool success
) {
157 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
158 if (!done_
.is_null())
160 ? extensions::api::file_manager_private::TASK_RESULT_OPENED
161 : extensions::api::file_manager_private::TASK_RESULT_FAILED
);