1 // Copyright 2015 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/extensions/file_manager/job_event_router.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "chrome/browser/chromeos/file_manager/app_id.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "components/drive/file_system_core_util.h"
13 #include "content/public/browser/browser_thread.h"
15 using content::BrowserThread
;
16 namespace file_manager_private
= extensions::api::file_manager_private
;
18 namespace file_manager
{
21 // Utility function to check if |job_info| is a file uploading job.
22 bool IsUploadJob(drive::JobType type
) {
23 return (type
== drive::TYPE_UPLOAD_NEW_FILE
||
24 type
== drive::TYPE_UPLOAD_EXISTING_FILE
);
29 JobEventRouter::JobEventRouter(const base::TimeDelta
& event_delay
)
30 : event_delay_(event_delay
),
31 num_completed_bytes_(0),
36 JobEventRouter::~JobEventRouter() {
39 void JobEventRouter::OnJobAdded(const drive::JobInfo
& job_info
) {
40 OnJobUpdated(job_info
);
43 void JobEventRouter::OnJobUpdated(const drive::JobInfo
& job_info
) {
44 DCHECK(thread_checker_
.CalledOnValidThread());
45 if (!drive::IsActiveFileTransferJobInfo(job_info
))
49 UpdateBytes(job_info
);
50 drive_jobs_
[job_info
.job_id
] = make_linked_ptr(new drive::JobInfo(job_info
));
52 ScheduleDriveFileTransferEvent(
53 job_info
, file_manager_private::TRANSFER_STATE_IN_PROGRESS
,
54 false /* immediate */);
57 void JobEventRouter::OnJobDone(const drive::JobInfo
& job_info
,
58 drive::FileError error
) {
59 DCHECK(thread_checker_
.CalledOnValidThread());
60 if (!drive::IsActiveFileTransferJobInfo(job_info
))
63 const file_manager_private::TransferState state
=
64 error
== drive::FILE_ERROR_OK
65 ? file_manager_private::TRANSFER_STATE_COMPLETED
66 : file_manager_private::TRANSFER_STATE_FAILED
;
68 drive::JobInfo completed_job
= job_info
;
69 completed_job
.num_completed_bytes
= completed_job
.num_total_bytes
;
70 UpdateBytes(completed_job
);
72 ScheduleDriveFileTransferEvent(job_info
, state
, true /* immediate */);
74 // Forget about the job.
75 drive_jobs_
.erase(job_info
.job_id
);
76 if (!drive_jobs_
.size()) {
77 num_completed_bytes_
= 0L;
78 num_total_bytes_
= 0L;
82 void JobEventRouter::UpdateBytes(const drive::JobInfo
& job_info
) {
83 int64 last_completed_bytes
= 0;
84 int64 last_total_bytes
= 0;
85 if (drive_jobs_
.count(job_info
.job_id
)) {
86 last_completed_bytes
= drive_jobs_
[job_info
.job_id
]->num_completed_bytes
;
87 last_total_bytes
= drive_jobs_
[job_info
.job_id
]->num_total_bytes
;
89 num_completed_bytes_
+= job_info
.num_completed_bytes
- last_completed_bytes
;
90 num_total_bytes_
+= job_info
.num_total_bytes
- last_total_bytes
;
93 void JobEventRouter::ScheduleDriveFileTransferEvent(
94 const drive::JobInfo
& job_info
,
95 file_manager_private::TransferState state
,
97 const bool no_pending_task
= !pending_event_
;
99 // Update the latest event.
100 pending_event_
.reset(new file_manager_private::FileTransferStatus
);
102 ConvertDrivePathToFileSystemUrl(job_info
.file_path
, kFileManagerAppId
);
103 pending_event_
->file_url
= url
.spec();
104 pending_event_
->transfer_state
= state
;
105 pending_event_
->transfer_type
=
106 IsUploadJob(job_info
.job_type
)
107 ? file_manager_private::TRANSFER_TYPE_UPLOAD
108 : file_manager_private::TRANSFER_TYPE_DOWNLOAD
;
111 SendDriveFileTransferEvent();
112 } else if (no_pending_task
) {
113 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
114 FROM_HERE
, base::Bind(&JobEventRouter::SendDriveFileTransferEvent
,
115 weak_factory_
.GetWeakPtr()),
120 void JobEventRouter::SendDriveFileTransferEvent() {
123 // JavaScript does not have 64-bit integers. Instead we use double, which
124 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice
125 // in C++. Larger values are rounded.
126 pending_event_
->num_total_jobs
= drive_jobs_
.size();
127 pending_event_
->processed
= num_completed_bytes_
;
128 pending_event_
->total
= num_total_bytes_
;
131 extensions::events::FILE_MANAGER_PRIVATE_ON_FILE_TRANSFERS_UPDATED
,
132 file_manager_private::OnFileTransfersUpdated::kEventName
,
133 file_manager_private::OnFileTransfersUpdated::Create(*pending_event_
));
134 pending_event_
.reset();
137 } // namespace file_manager