Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: chrome/browser/chromeos/extensions/file_manager/event_router.cc

Issue 507293002: Enrich fileBrowserPrivate.onFileTransfersUpdated event to support displaying total number of jobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 int64 kFileTransferEventDelayTime = 100;
kinaba 2014/09/02 05:01:39 Could you add the uint (millisecond?) of the value
iseki 2014/09/02 10:01:42 Done.
81 // This time is used for sending a event forcely.
82 const int64 kFileTransferEventForceSendInterval = 500;
kinaba 2014/09/02 05:01:39 ditto
iseki 2014/09/02 10:01:42 Done.
83
77 // Utility function to check if |job_info| is a file uploading job. 84 // Utility function to check if |job_info| is a file uploading job.
78 bool IsUploadJob(drive::JobType type) { 85 bool IsUploadJob(drive::JobType type) {
79 return (type == drive::TYPE_UPLOAD_NEW_FILE || 86 return (type == drive::TYPE_UPLOAD_NEW_FILE ||
80 type == drive::TYPE_UPLOAD_EXISTING_FILE); 87 type == drive::TYPE_UPLOAD_EXISTING_FILE);
81 } 88 }
82 89
83 // Converts the job info to a IDL generated type. 90 // Converts the job info to a IDL generated type.
84 void JobInfoToTransferStatus( 91 void JobInfoToTransferStatus(
85 Profile* profile, 92 Profile* profile,
86 const std::string& extension_id, 93 const std::string& extension_id,
87 const std::string& job_status, 94 const std::string& job_status,
88 const drive::JobInfo& job_info, 95 const drive::JobInfo& job_info,
89 file_browser_private::FileTransferStatus* status) { 96 file_browser_private::FileTransferStatus* status) {
90 DCHECK(IsActiveFileTransferJobInfo(job_info)); 97 DCHECK(IsActiveFileTransferJobInfo(job_info));
91 98
92 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); 99 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
93 GURL url = util::ConvertDrivePathToFileSystemUrl( 100 GURL url = util::ConvertDrivePathToFileSystemUrl(
94 profile, job_info.file_path, extension_id); 101 profile, job_info.file_path, extension_id);
95 status->file_url = url.spec(); 102 status->file_url = url.spec();
96 status->transfer_state = file_browser_private::ParseTransferState(job_status); 103 status->transfer_state = file_browser_private::ParseTransferState(job_status);
97 status->transfer_type = 104 status->transfer_type =
98 IsUploadJob(job_info.job_type) ? 105 IsUploadJob(job_info.job_type) ?
99 file_browser_private::TRANSFER_TYPE_UPLOAD : 106 file_browser_private::TRANSFER_TYPE_UPLOAD :
100 file_browser_private::TRANSFER_TYPE_DOWNLOAD; 107 file_browser_private::TRANSFER_TYPE_DOWNLOAD;
108 status->num_total_jobs = job_info.num_total_jobs;
101 // JavaScript does not have 64-bit integers. Instead we use double, which 109 // 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 110 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice
103 // in C++. Larger values are rounded. 111 // in C++. Larger values are rounded.
104 status->processed.reset( 112 status->processed.reset(
105 new double(static_cast<double>(job_info.num_completed_bytes))); 113 new double(static_cast<double>(job_info.num_completed_bytes)));
106 status->total.reset( 114 status->total.reset(
107 new double(static_cast<double>(job_info.num_total_bytes))); 115 new double(static_cast<double>(job_info.num_total_bytes)));
108 } 116 }
109 117
110 // Checks if the Recovery Tool is running. This is a temporary solution. 118 // Checks if the Recovery Tool is running. This is a temporary solution.
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 } 621 }
614 622
615 BroadcastEvent( 623 BroadcastEvent(
616 profile_, 624 profile_,
617 file_browser_private::OnPreferencesChanged::kEventName, 625 file_browser_private::OnPreferencesChanged::kEventName,
618 file_browser_private::OnPreferencesChanged::Create()); 626 file_browser_private::OnPreferencesChanged::Create());
619 } 627 }
620 628
621 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { 629 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) {
622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
623 OnJobUpdated(job_info); 631 if (!drive::IsActiveFileTransferJobInfo(job_info))
632 return;
633 ScheduleDriveFileTransferEvent(
634 job_info, kFileTransferStateAdded, false /* immediate */);
624 } 635 }
625 636
626 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { 637 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) {
627 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
628 if (!drive::IsActiveFileTransferJobInfo(job_info)) 639 if (!drive::IsActiveFileTransferJobInfo(job_info))
629 return; 640 return;
630 641
631 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); 642 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end());
632 643
644 const std::string status =
645 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress;
646
633 // Replace with the latest job info. 647 // Replace with the latest job info.
634 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( 648 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus(job_info, status);
635 job_info,
636 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress);
637 649
638 // Fire event if needed. 650 ScheduleDriveFileTransferEvent(job_info, status, false /* immediate */);
639 bool always = is_new_job;
640 SendDriveFileTransferEvent(always);
641 } 651 }
642 652
643 void EventRouter::OnJobDone(const drive::JobInfo& job_info, 653 void EventRouter::OnJobDone(const drive::JobInfo& job_info,
644 drive::FileError error) { 654 drive::FileError error) {
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
646 if (!drive::IsActiveFileTransferJobInfo(job_info)) 656 if (!drive::IsActiveFileTransferJobInfo(job_info))
647 return; 657 return;
648 658
649 // Replace with the latest job info. 659 const std::string status = error == drive::FILE_ERROR_OK
650 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( 660 ? kFileTransferStateCompleted
651 job_info, 661 : kFileTransferStateFailed;
652 error == drive::FILE_ERROR_OK ? kFileTransferStateCompleted
653 : kFileTransferStateFailed);
654 662
655 // Fire event if needed. 663 ScheduleDriveFileTransferEvent(job_info, status, true /* immediate */);
656 bool always = true;
657 SendDriveFileTransferEvent(always);
658 664
659 // Forget about the job. 665 // Forget about the job.
660 drive_jobs_.erase(job_info.job_id); 666 drive_jobs_.erase(job_info.job_id);
661 } 667 }
662 668
663 void EventRouter::SendDriveFileTransferEvent(bool always) { 669 void EventRouter::ScheduleDriveFileTransferEvent(const drive::JobInfo& job_info,
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 670 const std::string& status,
671 bool immediate) {
672 // Update next send time.
673 const base::Time now = base::Time::Now();
674 if (immediate) {
675 next_send_file_transfer_event_ = now;
676 } else if (!drive_job_info_with_status_) {
677 // The first job is delayed to confirm whether only job or many jobs.
678 next_send_file_transfer_event_ = std::max(
679 now + base::TimeDelta::FromMilliseconds(kFileTransferEventDelayTime),
680 next_send_file_transfer_event_);
681 }
665 682
666 // When |always| flag is not set, we don't send the event until certain 683 // Update the latest event.
667 // amount of time passes after the previous one. This is to avoid 684 drive_job_info_with_status_.reset(
668 // flooding the IPC between extensions by many onFileTransferUpdated events. 685 new DriveJobInfoWithStatus(job_info, status));
669 if (!ShouldSendProgressEvent(always, &last_file_transfer_event_)) 686
687 // Schedule event.
688 if (next_send_file_transfer_event_ < now) {
689 SendDriveFileTransferEvent();
690 } else {
691 const base::TimeDelta delta = next_send_file_transfer_event_ - now;
692 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
693 FROM_HERE,
694 base::Bind(&EventRouter::SendDriveFileTransferEvent,
695 weak_factory_.GetWeakPtr()),
696 delta);
697 }
698 }
699
700 void EventRouter::SendDriveFileTransferEvent() {
701 const base::Time now = base::Time::Now();
702 if (now < next_send_file_transfer_event_ || !drive_job_info_with_status_)
kinaba 2014/09/02 05:01:39 This may be fragile due to reasons. First, accord
iseki 2014/09/02 10:01:42 Done.
670 return; 703 return;
671 704
672 // Convert the current |drive_jobs_| to IDL type. 705 // Convert the drive_job_info_with_status_ to IDL type.
673 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > 706 std::vector<linked_ptr<file_browser_private::FileTransferStatus> >
674 status_list; 707 status_list;
675 for (std::map<drive::JobID, DriveJobInfoWithStatus>::iterator 708
676 iter = drive_jobs_.begin(); iter != drive_jobs_.end(); ++iter) { 709 linked_ptr<file_browser_private::FileTransferStatus> status(
677 linked_ptr<file_browser_private::FileTransferStatus> status( 710 new file_browser_private::FileTransferStatus());
678 new file_browser_private::FileTransferStatus()); 711 JobInfoToTransferStatus(profile_,
679 JobInfoToTransferStatus(profile_, 712 kFileManagerAppId,
680 kFileManagerAppId, 713 drive_job_info_with_status_->status,
681 iter->second.status, 714 drive_job_info_with_status_->job_info,
682 iter->second.job_info, 715 status.get());
683 status.get()); 716 status_list.push_back(status);
kinaba 2014/09/02 05:01:39 Previously the onFileTransferUpdated event sent al
iseki 2014/09/02 10:01:42 I make the clean up issue(crbug.com/408482) and tr
684 status_list.push_back(status); 717
685 } 718 drive_job_info_with_status_.reset();
719
686 BroadcastEvent( 720 BroadcastEvent(
687 profile_, 721 profile_,
688 file_browser_private::OnFileTransfersUpdated::kEventName, 722 file_browser_private::OnFileTransfersUpdated::kEventName,
689 file_browser_private::OnFileTransfersUpdated::Create(status_list)); 723 file_browser_private::OnFileTransfersUpdated::Create(status_list));
724 // To avoid terriable delay due to dense consecutive event, set the
725 // force send time.
kinaba 2014/09/02 05:01:39 I couldn't see how it works, or what is it for. I
iseki 2014/09/02 10:01:42 Done.
726 next_send_file_transfer_event_ =
727 now +
728 base::TimeDelta::FromMilliseconds(kFileTransferEventForceSendInterval);
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698