OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/extensions/file_manager/event_router.h" | 5 #include "chrome/browser/chromeos/extensions/file_manager/event_router.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/prefs/pref_change_registrar.h" | 10 #include "base/prefs/pref_change_registrar.h" |
11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/thread_task_runner_handle.h" | |
13 #include "base/threading/sequenced_worker_pool.h" | 14 #include "base/threading/sequenced_worker_pool.h" |
14 #include "base/values.h" | 15 #include "base/values.h" |
15 #include "chrome/browser/app_mode/app_mode_utils.h" | 16 #include "chrome/browser/app_mode/app_mode_utils.h" |
16 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
17 #include "chrome/browser/chromeos/drive/drive_integration_service.h" | 18 #include "chrome/browser/chromeos/drive/drive_integration_service.h" |
18 #include "chrome/browser/chromeos/drive/file_change.h" | 19 #include "chrome/browser/chromeos/drive/file_change.h" |
19 #include "chrome/browser/chromeos/drive/file_system_interface.h" | 20 #include "chrome/browser/chromeos/drive/file_system_interface.h" |
20 #include "chrome/browser/chromeos/drive/file_system_util.h" | 21 #include "chrome/browser/chromeos/drive/file_system_util.h" |
21 #include "chrome/browser/chromeos/extensions/file_manager/device_event_router.h" | 22 #include "chrome/browser/chromeos/extensions/file_manager/device_event_router.h" |
22 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" | 23 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 using drive::DriveIntegrationService; | 55 using drive::DriveIntegrationService; |
55 using drive::DriveIntegrationServiceFactory; | 56 using drive::DriveIntegrationServiceFactory; |
56 using file_manager::util::EntryDefinition; | 57 using file_manager::util::EntryDefinition; |
57 using file_manager::util::FileDefinition; | 58 using file_manager::util::FileDefinition; |
58 | 59 |
59 namespace file_browser_private = extensions::api::file_browser_private; | 60 namespace file_browser_private = extensions::api::file_browser_private; |
60 | 61 |
61 namespace file_manager { | 62 namespace file_manager { |
62 namespace { | 63 namespace { |
63 // Constants for the "transferState" field of onFileTransferUpdated event. | 64 // Constants for the "transferState" field of onFileTransferUpdated event. |
65 const char kFileTransferStateAdded[] = "added"; | |
64 const char kFileTransferStateStarted[] = "started"; | 66 const char kFileTransferStateStarted[] = "started"; |
65 const char kFileTransferStateInProgress[] = "in_progress"; | 67 const char kFileTransferStateInProgress[] = "in_progress"; |
66 const char kFileTransferStateCompleted[] = "completed"; | 68 const char kFileTransferStateCompleted[] = "completed"; |
67 const char kFileTransferStateFailed[] = "failed"; | 69 const char kFileTransferStateFailed[] = "failed"; |
68 | 70 |
69 // Frequency of sending onFileTransferUpdated. | 71 // Frequency of sending onFileTransferUpdated. |
70 const int64 kProgressEventFrequencyInMilliseconds = 1000; | 72 const int64 kProgressEventFrequencyInMilliseconds = 1000; |
71 | 73 |
72 // Maximim size of detailed change info on directory change event. If the size | 74 // Maximim size of detailed change info on directory change event. If the size |
73 // exceeds the maximum size, the detailed info is omitted and the force refresh | 75 // exceeds the maximum size, the detailed info is omitted and the force refresh |
74 // is kicked. | 76 // is kicked. |
75 const size_t kDirectoryChangeEventMaxDetailInfoSize = 1000; | 77 const size_t kDirectoryChangeEventMaxDetailInfoSize = 1000; |
76 | 78 |
79 // This time is used for confirm following event exists. | |
80 const base::TimeDelta file_transfer_event_delay_time = | |
hirono
2014/09/01 12:04:54
We don't have constants of non-primitive types. So
iseki
2014/09/02 01:05:43
Done.
| |
81 base::TimeDelta::FromMilliseconds(100); | |
82 // This time is used for sending a event forcely. | |
83 const base::TimeDelta file_transfer_event_force_send_interval = | |
84 base::TimeDelta::FromMilliseconds(500); | |
85 | |
77 // Utility function to check if |job_info| is a file uploading job. | 86 // Utility function to check if |job_info| is a file uploading job. |
78 bool IsUploadJob(drive::JobType type) { | 87 bool IsUploadJob(drive::JobType type) { |
79 return (type == drive::TYPE_UPLOAD_NEW_FILE || | 88 return (type == drive::TYPE_UPLOAD_NEW_FILE || |
80 type == drive::TYPE_UPLOAD_EXISTING_FILE); | 89 type == drive::TYPE_UPLOAD_EXISTING_FILE); |
81 } | 90 } |
82 | 91 |
83 // Converts the job info to a IDL generated type. | 92 // Converts the job info to a IDL generated type. |
84 void JobInfoToTransferStatus( | 93 void JobInfoToTransferStatus( |
85 Profile* profile, | 94 Profile* profile, |
86 const std::string& extension_id, | 95 const std::string& extension_id, |
87 const std::string& job_status, | 96 const std::string& job_status, |
88 const drive::JobInfo& job_info, | 97 const drive::JobInfo& job_info, |
89 file_browser_private::FileTransferStatus* status) { | 98 file_browser_private::FileTransferStatus* status) { |
90 DCHECK(IsActiveFileTransferJobInfo(job_info)); | 99 DCHECK(IsActiveFileTransferJobInfo(job_info)); |
91 | 100 |
92 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); | 101 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); |
93 GURL url = util::ConvertDrivePathToFileSystemUrl( | 102 GURL url = util::ConvertDrivePathToFileSystemUrl( |
94 profile, job_info.file_path, extension_id); | 103 profile, job_info.file_path, extension_id); |
95 status->file_url = url.spec(); | 104 status->file_url = url.spec(); |
96 status->transfer_state = file_browser_private::ParseTransferState(job_status); | 105 status->transfer_state = file_browser_private::ParseTransferState(job_status); |
97 status->transfer_type = | 106 status->transfer_type = |
98 IsUploadJob(job_info.job_type) ? | 107 IsUploadJob(job_info.job_type) ? |
99 file_browser_private::TRANSFER_TYPE_UPLOAD : | 108 file_browser_private::TRANSFER_TYPE_UPLOAD : |
100 file_browser_private::TRANSFER_TYPE_DOWNLOAD; | 109 file_browser_private::TRANSFER_TYPE_DOWNLOAD; |
110 status->num_total_jobs = job_info.num_total_jobs; | |
101 // JavaScript does not have 64-bit integers. Instead we use double, which | 111 // JavaScript does not have 64-bit integers. Instead we use double, which |
102 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice | 112 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice |
103 // in C++. Larger values are rounded. | 113 // in C++. Larger values are rounded. |
104 status->processed.reset( | 114 status->processed.reset( |
105 new double(static_cast<double>(job_info.num_completed_bytes))); | 115 new double(static_cast<double>(job_info.num_completed_bytes))); |
106 status->total.reset( | 116 status->total.reset( |
107 new double(static_cast<double>(job_info.num_total_bytes))); | 117 new double(static_cast<double>(job_info.num_total_bytes))); |
108 } | 118 } |
109 | 119 |
110 // Checks if the Recovery Tool is running. This is a temporary solution. | 120 // Checks if the Recovery Tool is running. This is a temporary solution. |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 } | 623 } |
614 | 624 |
615 BroadcastEvent( | 625 BroadcastEvent( |
616 profile_, | 626 profile_, |
617 file_browser_private::OnPreferencesChanged::kEventName, | 627 file_browser_private::OnPreferencesChanged::kEventName, |
618 file_browser_private::OnPreferencesChanged::Create()); | 628 file_browser_private::OnPreferencesChanged::Create()); |
619 } | 629 } |
620 | 630 |
621 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { | 631 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { |
622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 632 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
623 OnJobUpdated(job_info); | 633 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
634 return; | |
635 ScheduleDriveFileTransferEvent( | |
636 job_info, kFileTransferStateAdded, false /* immediate */); | |
624 } | 637 } |
625 | 638 |
626 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { | 639 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { |
627 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
628 if (!drive::IsActiveFileTransferJobInfo(job_info)) | 641 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
629 return; | 642 return; |
630 | 643 |
631 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); | 644 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); |
632 | 645 |
646 const std::string status = | |
647 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress; | |
648 | |
633 // Replace with the latest job info. | 649 // Replace with the latest job info. |
634 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( | 650 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus(job_info, status); |
635 job_info, | |
636 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress); | |
637 | 651 |
638 // Fire event if needed. | 652 ScheduleDriveFileTransferEvent(job_info, status, false /* immediate */); |
639 bool always = is_new_job; | |
640 SendDriveFileTransferEvent(always); | |
641 } | 653 } |
642 | 654 |
643 void EventRouter::OnJobDone(const drive::JobInfo& job_info, | 655 void EventRouter::OnJobDone(const drive::JobInfo& job_info, |
644 drive::FileError error) { | 656 drive::FileError error) { |
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
646 if (!drive::IsActiveFileTransferJobInfo(job_info)) | 658 if (!drive::IsActiveFileTransferJobInfo(job_info)) |
647 return; | 659 return; |
648 | 660 |
649 // Replace with the latest job info. | 661 const std::string status = error == drive::FILE_ERROR_OK |
650 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( | 662 ? kFileTransferStateCompleted |
hirono
2014/09/01 12:04:54
Please run git cl before uploading the next patch.
iseki
2014/09/02 01:05:43
Done.
| |
651 job_info, | 663 : kFileTransferStateFailed; |
652 error == drive::FILE_ERROR_OK ? kFileTransferStateCompleted | |
653 : kFileTransferStateFailed); | |
654 | 664 |
655 // Fire event if needed. | 665 ScheduleDriveFileTransferEvent(job_info, status, true /* immediate */); |
656 bool always = true; | |
657 SendDriveFileTransferEvent(always); | |
658 | 666 |
659 // Forget about the job. | 667 // Forget about the job. |
660 drive_jobs_.erase(job_info.job_id); | 668 drive_jobs_.erase(job_info.job_id); |
661 } | 669 } |
662 | 670 |
663 void EventRouter::SendDriveFileTransferEvent(bool always) { | 671 void EventRouter::ScheduleDriveFileTransferEvent(const drive::JobInfo& job_info, |
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 672 const std::string& status, |
673 bool immediate) { | |
674 // Update next send time. | |
675 const base::Time now = base::Time::Now(); | |
676 if (immediate) { | |
677 next_send_file_transfer_event_ = now; | |
678 } else if (!drive_job_info_with_status_) { | |
679 // The first job is delayed to confirm whether only job or many jobs. | |
680 next_send_file_transfer_event_ = std::max( | |
681 now + file_transfer_event_delay_time, next_send_file_transfer_event_); | |
682 } | |
665 | 683 |
666 // When |always| flag is not set, we don't send the event until certain | 684 // Update the latest event. |
667 // amount of time passes after the previous one. This is to avoid | 685 drive_job_info_with_status_.reset( |
668 // flooding the IPC between extensions by many onFileTransferUpdated events. | 686 new DriveJobInfoWithStatus(job_info, status)); |
669 if (!ShouldSendProgressEvent(always, &last_file_transfer_event_)) | 687 |
688 // Schedule event. | |
689 if (next_send_file_transfer_event_ < now) { | |
690 SendDriveFileTransferEvent(); | |
691 } else { | |
692 const base::TimeDelta delta = next_send_file_transfer_event_ - now; | |
693 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
694 FROM_HERE, | |
695 base::Bind(&EventRouter::SendDriveFileTransferEvent, | |
696 weak_factory_.GetWeakPtr()), | |
697 delta); | |
698 } | |
699 } | |
700 | |
701 void EventRouter::SendDriveFileTransferEvent() { | |
702 base::Time now = base::Time::Now(); | |
hirono
2014/09/01 12:04:54
const
iseki
2014/09/02 01:05:43
Done.
| |
703 if (now < next_send_file_transfer_event_ || !drive_job_info_with_status_) | |
670 return; | 704 return; |
671 | 705 |
672 // Convert the current |drive_jobs_| to IDL type. | 706 // Convert the drive_job_info_with_status_ to IDL type. |
673 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > | 707 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > |
674 status_list; | 708 status_list; |
675 for (std::map<drive::JobID, DriveJobInfoWithStatus>::iterator | 709 |
676 iter = drive_jobs_.begin(); iter != drive_jobs_.end(); ++iter) { | 710 linked_ptr<file_browser_private::FileTransferStatus> status( |
677 linked_ptr<file_browser_private::FileTransferStatus> status( | 711 new file_browser_private::FileTransferStatus()); |
678 new file_browser_private::FileTransferStatus()); | 712 JobInfoToTransferStatus(profile_, |
679 JobInfoToTransferStatus(profile_, | 713 kFileManagerAppId, |
680 kFileManagerAppId, | 714 drive_job_info_with_status_->status, |
681 iter->second.status, | 715 drive_job_info_with_status_->job_info, |
682 iter->second.job_info, | 716 status.get()); |
683 status.get()); | 717 status_list.push_back(status); |
684 status_list.push_back(status); | 718 |
685 } | 719 drive_job_info_with_status_.reset(); |
720 | |
686 BroadcastEvent( | 721 BroadcastEvent( |
687 profile_, | 722 profile_, |
688 file_browser_private::OnFileTransfersUpdated::kEventName, | 723 file_browser_private::OnFileTransfersUpdated::kEventName, |
689 file_browser_private::OnFileTransfersUpdated::Create(status_list)); | 724 file_browser_private::OnFileTransfersUpdated::Create(status_list)); |
725 // To avoid terriable delay due to dense consecutive event, set the | |
hirono
2014/09/01 12:04:54
Please fix "... set the the force ..." -> "... set
iseki
2014/09/02 01:05:43
Done.
| |
726 // the force send time. | |
727 next_send_file_transfer_event_ = | |
728 now + file_transfer_event_force_send_interval; | |
690 } | 729 } |
691 | 730 |
692 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) { | 731 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) { |
693 HandleFileWatchNotification(NULL, drive_path, false); | 732 HandleFileWatchNotification(NULL, drive_path, false); |
694 } | 733 } |
695 | 734 |
696 void EventRouter::OnFileChanged(const drive::FileChange& changed_files) { | 735 void EventRouter::OnFileChanged(const drive::FileChange& changed_files) { |
697 typedef std::map<base::FilePath, drive::FileChange> FileChangeMap; | 736 typedef std::map<base::FilePath, drive::FileChange> FileChangeMap; |
698 | 737 |
699 FileChangeMap map; | 738 FileChangeMap map; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
965 } | 1004 } |
966 } | 1005 } |
967 | 1006 |
968 void EventRouter::OnOwnerEntryChanged(aura::Window* window) { | 1007 void EventRouter::OnOwnerEntryChanged(aura::Window* window) { |
969 BroadcastEvent(profile_, | 1008 BroadcastEvent(profile_, |
970 file_browser_private::OnDesktopChanged::kEventName, | 1009 file_browser_private::OnDesktopChanged::kEventName, |
971 file_browser_private::OnDesktopChanged::Create()); | 1010 file_browser_private::OnDesktopChanged::Create()); |
972 } | 1011 } |
973 | 1012 |
974 } // namespace file_manager | 1013 } // namespace file_manager |
OLD | NEW |