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

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 30 matching lines...) Expand all
53 using drive::DriveIntegrationService; 54 using drive::DriveIntegrationService;
54 using drive::DriveIntegrationServiceFactory; 55 using drive::DriveIntegrationServiceFactory;
55 using file_manager::util::EntryDefinition; 56 using file_manager::util::EntryDefinition;
56 using file_manager::util::FileDefinition; 57 using file_manager::util::FileDefinition;
57 58
58 namespace file_browser_private = extensions::api::file_browser_private; 59 namespace file_browser_private = extensions::api::file_browser_private;
59 60
60 namespace file_manager { 61 namespace file_manager {
61 namespace { 62 namespace {
62 // Constants for the "transferState" field of onFileTransferUpdated event. 63 // Constants for the "transferState" field of onFileTransferUpdated event.
64 const char kFileTransferStateAdded[] = "added";
63 const char kFileTransferStateStarted[] = "started"; 65 const char kFileTransferStateStarted[] = "started";
64 const char kFileTransferStateInProgress[] = "in_progress"; 66 const char kFileTransferStateInProgress[] = "in_progress";
65 const char kFileTransferStateCompleted[] = "completed"; 67 const char kFileTransferStateCompleted[] = "completed";
66 const char kFileTransferStateFailed[] = "failed"; 68 const char kFileTransferStateFailed[] = "failed";
67 69
68 // Frequency of sending onFileTransferUpdated. 70 // Frequency of sending onFileTransferUpdated.
69 const int64 kProgressEventFrequencyInMilliseconds = 1000; 71 const int64 kProgressEventFrequencyInMilliseconds = 1000;
70 72
71 // Maximim size of detailed change info on directory change event. If the size 73 // Maximim size of detailed change info on directory change event. If the size
72 // exceeds the maximum size, the detailed info is omitted and the force refresh 74 // exceeds the maximum size, the detailed info is omitted and the force refresh
73 // is kicked. 75 // is kicked.
74 const size_t kDirectoryChangeEventMaxDetailInfoSize = 1000; 76 const size_t kDirectoryChangeEventMaxDetailInfoSize = 1000;
75 77
78 // This time(millisecond) is used for confirm following event exists.
79 const int64 kFileTransferEventDelayTimeInMilliseconds = 300;
80
76 // Utility function to check if |job_info| is a file uploading job. 81 // Utility function to check if |job_info| is a file uploading job.
77 bool IsUploadJob(drive::JobType type) { 82 bool IsUploadJob(drive::JobType type) {
78 return (type == drive::TYPE_UPLOAD_NEW_FILE || 83 return (type == drive::TYPE_UPLOAD_NEW_FILE ||
79 type == drive::TYPE_UPLOAD_EXISTING_FILE); 84 type == drive::TYPE_UPLOAD_EXISTING_FILE);
80 } 85 }
81 86
87 std::vector<drive::JobInfo> GetActiveFileTransferJobInfo(
kinaba 2014/09/03 15:54:18 You can simply return only the number of jobs size
iseki 2014/09/04 00:50:06 Done.
88 std::vector<drive::JobInfo> job_info_list) {
kinaba 2014/09/03 15:54:18 const std::vector<drive::JobInfo>& job_info_list
iseki 2014/09/04 00:50:07 Done.
89 std::vector<drive::JobInfo> active_job_info_list;
90 for (std::vector<drive::JobInfo>::iterator iter = job_info_list.begin(),
91 end = job_info_list.end();
kinaba 2014/09/03 15:54:18 (Though I personally prefer iterators :)), we are
iseki 2014/09/04 00:50:07 Done.
92 iter != end;
93 ++iter) {
94 if (IsActiveFileTransferJobInfo(*iter))
95 active_job_info_list.push_back(*iter);
96 }
97 return active_job_info_list;
98 }
99
82 // Converts the job info to a IDL generated type. 100 // Converts the job info to a IDL generated type.
83 void JobInfoToTransferStatus( 101 void JobInfoToTransferStatus(
84 Profile* profile, 102 Profile* profile,
85 const std::string& extension_id, 103 const std::string& extension_id,
86 const std::string& job_status, 104 const std::string& job_status,
87 const drive::JobInfo& job_info, 105 const drive::JobInfo& job_info,
88 file_browser_private::FileTransferStatus* status) { 106 file_browser_private::FileTransferStatus* status) {
89 DCHECK(IsActiveFileTransferJobInfo(job_info)); 107 DCHECK(IsActiveFileTransferJobInfo(job_info));
90 108
91 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); 109 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
92 GURL url = util::ConvertDrivePathToFileSystemUrl( 110 GURL url = util::ConvertDrivePathToFileSystemUrl(
93 profile, job_info.file_path, extension_id); 111 profile, job_info.file_path, extension_id);
94 status->file_url = url.spec(); 112 status->file_url = url.spec();
95 status->transfer_state = file_browser_private::ParseTransferState(job_status); 113 status->transfer_state = file_browser_private::ParseTransferState(job_status);
96 status->transfer_type = 114 status->transfer_type =
97 IsUploadJob(job_info.job_type) ? 115 IsUploadJob(job_info.job_type) ?
98 file_browser_private::TRANSFER_TYPE_UPLOAD : 116 file_browser_private::TRANSFER_TYPE_UPLOAD :
99 file_browser_private::TRANSFER_TYPE_DOWNLOAD; 117 file_browser_private::TRANSFER_TYPE_DOWNLOAD;
118 DriveIntegrationService* const integration_service =
119 DriveIntegrationServiceFactory::FindForProfile(profile);
120 status->num_total_jobs =
121 GetActiveFileTransferJobInfo(
122 integration_service->job_list()->GetJobInfoList()).size();
100 // JavaScript does not have 64-bit integers. Instead we use double, which 123 // JavaScript does not have 64-bit integers. Instead we use double, which
101 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice 124 // is in IEEE 754 formant and accurate up to 52-bits in JS, and in practice
102 // in C++. Larger values are rounded. 125 // in C++. Larger values are rounded.
103 status->processed.reset( 126 status->processed.reset(
104 new double(static_cast<double>(job_info.num_completed_bytes))); 127 new double(static_cast<double>(job_info.num_completed_bytes)));
105 status->total.reset( 128 status->total.reset(
106 new double(static_cast<double>(job_info.num_total_bytes))); 129 new double(static_cast<double>(job_info.num_total_bytes)));
107 } 130 }
108 131
109 // Checks if the Recovery Tool is running. This is a temporary solution. 132 // Checks if the Recovery Tool is running. This is a temporary solution.
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 } 606 }
584 607
585 BroadcastEvent( 608 BroadcastEvent(
586 profile_, 609 profile_,
587 file_browser_private::OnPreferencesChanged::kEventName, 610 file_browser_private::OnPreferencesChanged::kEventName,
588 file_browser_private::OnPreferencesChanged::Create()); 611 file_browser_private::OnPreferencesChanged::Create());
589 } 612 }
590 613
591 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) { 614 void EventRouter::OnJobAdded(const drive::JobInfo& job_info) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 615 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
593 OnJobUpdated(job_info); 616 if (!drive::IsActiveFileTransferJobInfo(job_info))
617 return;
618 ScheduleDriveFileTransferEvent(
619 job_info, kFileTransferStateAdded, false /* immediate */);
594 } 620 }
595 621
596 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) { 622 void EventRouter::OnJobUpdated(const drive::JobInfo& job_info) {
597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
598 if (!drive::IsActiveFileTransferJobInfo(job_info)) 624 if (!drive::IsActiveFileTransferJobInfo(job_info))
599 return; 625 return;
600 626
601 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end()); 627 bool is_new_job = (drive_jobs_.find(job_info.job_id) == drive_jobs_.end());
602 628
629 const std::string status =
630 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress;
kinaba 2014/09/03 15:54:18 Just a question, do we need to distinguish these t
iseki 2014/09/04 00:50:07 Now, kFileTransferStateInProgress is not necessary
631
603 // Replace with the latest job info. 632 // Replace with the latest job info.
604 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( 633 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus(job_info, status);
605 job_info,
606 is_new_job ? kFileTransferStateStarted : kFileTransferStateInProgress);
607 634
608 // Fire event if needed. 635 ScheduleDriveFileTransferEvent(job_info, status, false /* immediate */);
609 bool always = is_new_job;
610 SendDriveFileTransferEvent(always);
611 } 636 }
612 637
613 void EventRouter::OnJobDone(const drive::JobInfo& job_info, 638 void EventRouter::OnJobDone(const drive::JobInfo& job_info,
614 drive::FileError error) { 639 drive::FileError error) {
615 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
616 if (!drive::IsActiveFileTransferJobInfo(job_info)) 641 if (!drive::IsActiveFileTransferJobInfo(job_info))
617 return; 642 return;
618 643
619 // Replace with the latest job info. 644 const std::string status = error == drive::FILE_ERROR_OK
620 drive_jobs_[job_info.job_id] = DriveJobInfoWithStatus( 645 ? kFileTransferStateCompleted
621 job_info, 646 : kFileTransferStateFailed;
622 error == drive::FILE_ERROR_OK ? kFileTransferStateCompleted
623 : kFileTransferStateFailed);
624 647
625 // Fire event if needed. 648 ScheduleDriveFileTransferEvent(job_info, status, true /* immediate */);
626 bool always = true;
627 SendDriveFileTransferEvent(always);
628 649
629 // Forget about the job. 650 // Forget about the job.
630 drive_jobs_.erase(job_info.job_id); 651 drive_jobs_.erase(job_info.job_id);
631 } 652 }
632 653
633 void EventRouter::SendDriveFileTransferEvent(bool always) { 654 void EventRouter::ScheduleDriveFileTransferEvent(const drive::JobInfo& job_info,
634 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 655 const std::string& status,
656 bool immediate) {
657 const bool no_pending_task = !drive_job_info_for_scheduled_event_;
658 // Update the latest event.
659 drive_job_info_for_scheduled_event_.reset(
660 new DriveJobInfoWithStatus(job_info, status));
661 if (immediate) {
662 SendDriveFileTransferEvent();
663 } else if (no_pending_task) {
664 const base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
665 kFileTransferEventDelayTimeInMilliseconds);
666 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
667 FROM_HERE,
668 base::Bind(&EventRouter::SendDriveFileTransferEvent,
669 weak_factory_.GetWeakPtr()),
670 delay);
671 }
672 }
635 673
636 // When |always| flag is not set, we don't send the event until certain 674 void EventRouter::SendDriveFileTransferEvent() {
637 // amount of time passes after the previous one. This is to avoid 675 if (!drive_job_info_for_scheduled_event_)
638 // flooding the IPC between extensions by many onFileTransferUpdated events.
639 if (!ShouldSendProgressEvent(always, &last_file_transfer_event_))
640 return; 676 return;
641 677
642 // Convert the current |drive_jobs_| to IDL type. 678 // Convert the drive_job_info_for_scheduled_event_ to IDL type.
643 std::vector<linked_ptr<file_browser_private::FileTransferStatus> > 679 std::vector<linked_ptr<file_browser_private::FileTransferStatus> >
644 status_list; 680 status_list;
645 for (std::map<drive::JobID, DriveJobInfoWithStatus>::iterator 681
646 iter = drive_jobs_.begin(); iter != drive_jobs_.end(); ++iter) { 682 linked_ptr<file_browser_private::FileTransferStatus> status(
647 linked_ptr<file_browser_private::FileTransferStatus> status( 683 new file_browser_private::FileTransferStatus());
648 new file_browser_private::FileTransferStatus()); 684 JobInfoToTransferStatus(profile_,
649 JobInfoToTransferStatus(profile_, 685 kFileManagerAppId,
650 kFileManagerAppId, 686 drive_job_info_for_scheduled_event_->status,
651 iter->second.status, 687 drive_job_info_for_scheduled_event_->job_info,
652 iter->second.job_info, 688 status.get());
653 status.get()); 689 status_list.push_back(status);
654 status_list.push_back(status); 690
655 } 691 drive_job_info_for_scheduled_event_.reset();
692
656 BroadcastEvent( 693 BroadcastEvent(
657 profile_, 694 profile_,
658 file_browser_private::OnFileTransfersUpdated::kEventName, 695 file_browser_private::OnFileTransfersUpdated::kEventName,
659 file_browser_private::OnFileTransfersUpdated::Create(status_list)); 696 file_browser_private::OnFileTransfersUpdated::Create(status_list));
660 } 697 }
661 698
662 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) { 699 void EventRouter::OnDirectoryChanged(const base::FilePath& drive_path) {
663 HandleFileWatchNotification(NULL, drive_path, false); 700 HandleFileWatchNotification(NULL, drive_path, false);
664 } 701 }
665 702
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 // Do nothing. 941 // Do nothing.
905 } 942 }
906 943
907 void EventRouter::OnFormatCompleted(const std::string& device_path, 944 void EventRouter::OnFormatCompleted(const std::string& device_path,
908 bool success) { 945 bool success) {
909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 946 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
910 // Do nothing. 947 // Do nothing.
911 } 948 }
912 949
913 } // namespace file_manager 950 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698